Boost.Coroutine2:學習使用Coroutine(協程)

function(函數)routine(例程)coroutine (協程)

函數,例程以及協程都是指一系列的操做的集合。
函數(有返回值)以及例程(沒有返回值)也被稱做subroutine(子例程),由於它們的執行過程一般在父例程以前結束。
協程則有所不一樣,它是例程通常化的結果。
協程的執行過程容許被ios

  • 中途掛起。(suspend)
  • 稍後恢復運行。(resume)

協程一般用於實現異步

  • 生成器。(generators)
  • 異步函數。(asynchronous functions)

二者的區別在於:async

  • 生成器的恢復執行由用戶顯式調用來決定。
  • 異步函數的恢復執行由後臺線程來決定。

boost::coroutines2::coroutine<>

boost::coroutines2::coroutine<>被用來實現協程。
它有兩個嵌套類型:pull_type和push_type。
pull_type能夠從push_type那裏接收並返回數據。
push_type能夠把數據傳給pull_type。函數

#include <iostream>
#include <boost/coroutine2/coroutine.hpp>
using namespace std;

int main()
{
    typedef boost::coroutines2::coroutine<int> coro_t;
    int max = 8;
    coro_t::pull_type source(
        [&](coro_t::push_type& sink){
            int first=1,second=1;
            sink(first);
            sink(second);
            for(int i=0;i<max;++i){
                int third=first+second;
                first=second;
                second=third;
                sink(third);
            }
        });

    for(auto i:source)
        cout << i <<  " ";
    cout << endl;

    coro_t::push_type sink(
        [&](coro_t::pull_type& source){
            while(source){
                cout << source.get() <<  " ";
                source();
            }
        });

    vector<int> v{1,1,2,3,5,8,13,21,34,55};
    copy(begin(v),end(v),begin(sink));
}

// 1 1 2 3 5 8 13 21 34 55 
// 1 1 2 3 5 8 13 21 34 55
  • 這是一個使用協程實現斐波那契數列生成器的例子。
  • 協程類的類型爲boost::coroutines2::coroutine<int>。也就是說協程和主線程間相互傳遞的數據類型爲int。
  • pull_type類型對象source在構建時使用一個lambda來初始化。該lambda帶有一個push_type的引用參數sink。使用sink能夠將數據傳回主線程。

C#同等功能的代碼以下spa

using System;
using System.Collections.Generic;

namespace Sample
{
    class Fibonacci
    {
        public static void Main(string[] args)
        {
            IEnumerable<int> Source(int max)
            {
                int first = 1, second = 1;
                yield return first;
                yield return second;
                for (int i = 0; i < max; ++i)
                {
                    int third = first + second;
                    first = second;
                    second = third;
                    yield return third;
                }
            }
            foreach (int i in Source(8))
                Console.Write($"{i} ");
            Console.WriteLine();

            var v = new List<int> { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 };
            void Sink()
            {
                foreach(int i in v)
                {
                    Console.Write($"{i} ");
                }
            }
            Sink();
        }
    }
}   

// 1 1 2 3 5 8 13 21 34 55
// 1 1 2 3 5 8 13 21 34 55
相關文章
相關標籤/搜索