• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

            路漫漫,長修遠,我們不能沒有錢
            隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
            數據加載中……

            boost::asio::coroutine 文檔翻譯 + 源碼解析

            文檔地址

            http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/coroutine.html

            文檔翻譯

            協程

            提供實現不需要棧的協程的支持

            class coroutine

            成員函數

            函數名 描述
            coroutine 構造成為初始化狀態
            is_child 如果是一個fork子協程的話返回true
            is_complete 如果到了終止狀態就返回true
            is_parent 如果是fork的父協程的話返回true

            coroutine 類可以用來實現無棧的協程。這個類自身被用來保存協程的狀態。
            coroutine 類可以支持復制構造和賦值。最大一個int的空間占用。可以當作基類使用

            class session : coroutine
            {
             // 。。。
            };

            或者作為一個數據項。

            class session
            {
              //。。。
              coroutine coro_;
            };

            或者設置作為一個lambda或者bind()的參數。 這種實現的重點是在協程存在的時候,這個對下必須不被釋放。

            偽關鍵字

            協程是聯合特定偽關鍵子使用的,這些偽關鍵字使用宏實現。這些宏被定義在
            #include <boost/asio/yield.hpp>

            可以通過下面的頭文件方便的undefine

            #include <boost/asio/unyield.hpp>

            reenter

            reenter宏是用來定義一段協程的。他僅僅接收1個參數 : 一個coroutine的指針或者引用。比如 , 如果基類是coroutine你可以這樣寫 :

            reenter (this)
            {
              //coroutine body 
            }

            如果coroutine是成員變量的話

            reenter (coro_)
            {
              // coroutine body 
            }

            當一段reenter代碼被執行的時候,直接跳轉到最近的一次yeild或者fork位置后執行。
            協程代碼段也可以是一個單獨的語句

            reenter (this) for (;;)
            {
              //。。。
            }

            局限性: 由于reenter宏是用swtich來實現的,所以你在協程代碼中定義局部變量的時候必須格外注意。 這個變量不能定義在重入的時候會被跳過的地方。

            yield 語句

            這種格式的 yield 關鍵字通常被用來做異步操作 :

            yield socket_->async_read_some(buffer(*buffer_), *this);

            這個分成4步驟實現:

            • yield 保存當前協程的狀態.
            • 初始化異步操作。
            • 繼續執行點被設置為下一行。
            • 控制跳轉到協程末尾,推出協程.。

            當異步操作完成后,再次執行這個協程。重入后從繼續執行點執行。記住,異步操作執行后再次調用協程是很重要的。

            1 yield
            2 {
            3   mutable_buffers_1 b = buffer(*buffer_);
            4   socket_->async_read_some(b, *this);
            5 }

            yield return expression ;

            這種形式通常被用來做基于協程的解析器。比如 :

             1 struct interleave : coroutine
             2 {
             3   istream& is1;
             4   istream& is2;
             5   char operator()(char c)
             6   {
             7     reenter (thisfor (;;)
             8     {
             9       yield return is1.get();
            10       yield return is2.get();
            11     }
            12   }
            13 };

            定義了一個小協程來間隔的從兩個流中讀取數據,

            這個分成3步驟實現

            • yield 保存當前協程的狀態.
            • 繼續執行點被設置為下一行。
            • 函數返回表達式的值

            yield ;

            This form of yield is equivalent to the following steps:

            這個分成3步驟實現

            • yield 保存當前協程的狀態.
            • 繼續執行點被設置為緊跟著分號。
            • 控制函數到達代碼末尾。
              這種格式在協程被用來組織線程的合作和調度的時候。比如 :
             1 struct task : coroutine
             2 {
             3   //。。。
             4   void operator()()
             5   {
             6     reenter (this)
             7     {
             8       while ( not finished )
             9       {
            10          do something 
            11         yield;
            12          do some more 
            13         yield;
            14       }
            15     }
            16   }
            17   //。。。
            18 };
            19 //。。。
            20 task t1, t2;
            21 for (;;)
            22 {
            23   t1();
            24   t2();
            25 }

            yield break ;

            最后一種格式是用來顯示的終止協程。分成兩步驟:

            • yeild將協程狀態設置為終止。
            • 控制函數到達代碼末尾。

            一旦協程終止。調用 is_complete()返回true 。 協程不能再被重入。
            注意 : 當協程代碼塊被顯示終止的時候,比如return , 拋出異常或者運行到結尾的時候,都會被設置為終止。

            fork statement

            fork偽關鍵字是用來使得一個協程分支的。它將一個協程分成兩個(或者更多)復制。一個使用場景是在服務器,產生一個新的協程來處理每個客戶端的鏈接。

             1 reenter (this)
             2 {
             3   do
             4   {
             5     socket_.reset(new tcp::socket(io_service_));
             6     yield acceptor->async_accept(*socket_, *this);
             7     fork server(*this)();
             8   } while (is_parent());
             9   // client-specific handling follows 
            10 }

            這個分4個步驟實現 :

            • fork 保存當前的協程狀態.
            • 創建一個協程的復制,要么立刻執行它,要么呆會。
            • 回復點緊跟著分號之后.
            • 對于父類,回復點在下一行。

            函數is_parenet()is_child()可以被用來區分父協程和自協程。你可以用他們來改變后面的工作順序。
            注意: fork 關鍵字并不真的實現分支。是程序來創建一個新的副本并調用它。你可以像上面那樣立刻執行,也可以利用類似io_server::post() 這樣的接口來延遲執行。

            替代的宏

            • BOOST_ASIO_CORO_REENTER instead of reenter
            • BOOST_ASIO_CORO_YIELD instead ofyield
            • BOOST_ASIO_CORO_FORK instead of fork

            源碼解析

            來源 :

            boost/asio/coroutine.hpp

             1 // 定義 coroutine 類, 本質上是一個行號記錄類。
             2 // 行號是這個東西沖入的唯一依據。
             3 class coroutine
             4 {
             5 public:
             6   // 初始化0
             7   /// Constructs a coroutine in its initial state.
             8   coroutine() : value_(0) {}
             9 
            10   // fork 的子協程初始行號是當前行號的負數。因此判斷它是否為負數。
            11   // 當子協程支持再fork后,value_變成新的行號,便不再被認為是child。 
            12   /// Returns true if the coroutine is the child of a fork.
            13   bool is_child() const { return value_ < 0; }
            14   // 返回 ! is_child()
            15   /// Returns true if the coroutine is the parent of a fork.
            16   bool is_parent() const { return !is_child(); }
            17 
            18   // 當reenter宏包被的模塊(里面應該有yeild或者fork , 否則這個模塊僅僅是普通的代碼塊,永遠不存在結束狀態)執行結束的時候,vaule_被設置為-1。
            19   /// Returns true if the coroutine has reached its terminal state.
            20   bool is_complete() const { return value_ == -1; }
            21 
            22 private:
            23   friend class detail::coroutine_ref;
            24   int value_;
            25 };
            26 
            27 
            28 namespace detail {
            29 // 引用類,使用這個類來方便的修改& 檢測coroutine 類的值。
            30 class coroutine_ref
            31 {
            32 public:
            33   coroutine_ref(coroutine& c) : value_(c.value_), modified_(false) {}
            34   coroutine_ref(coroutine* c) : value_(c->value_), modified_(false) {}
            35   ~coroutine_ref() { if (!modified_) value_ = -1; }
            36   operator int() const { return value_; }
            37   int& operator=(int v) { modified_ = truereturn value_ = v; }
            38 private:
            39   void operator=(const coroutine_ref&);
            40   int& value_;
            41   bool modified_;
            42 };
            43 
            44 // namespace detail
            45 // namespace asio
            46 // namespace boost
            47 
            48 #define BOOST_ASIO_CORO_REENTER(c) \
            49   switch (::boost::asio::detail::coroutine_ref _coro_value = c)\
            50     case -1if (_coro_value) \
            51     { \
            52       goto terminate_coroutine; \
            53       terminate_coroutine: /*這是標記reenter模塊結束的清理代碼*/\
            54       _coro_value = -1; \
            55       goto bail_out_of_coroutine; /*退出這次執行*/\
            56       bail_out_of_coroutine: \
            57       break; \
            58     } \
            59     else case 0/*下面是我們的代碼塊*/
            60 
            61 #define BOOST_ASIO_CORO_YIELD_IMPL(n) \
            62   for (_coro_value = (n);;) \
            63     if (_coro_value == 0) \
            64     { \
            65       case (n): /*當reenter模塊被重入的時候,根據行號直接跳轉到這里從而直接執行下一行*/; \
            66       break; \
            67     } \
            68     else /*第一次執行到這里*/\
            69       switch (_coro_value ? 0 : 1) \
            70         for (;;)  \
            71           case -1if (_coro_value)/*執行yeild break 終止 */ \
            72             goto terminate_coroutine; \
            73           else for (;;)/*執行yeild 而不是 yeild return 的話,循環 */\
            74             case 1if (_coro_value) \
            75               goto bail_out_of_coroutine; \
            76             else case 0:
            77 
            78 #define BOOST_ASIO_CORO_FORK_IMPL(n) \
            79   for (_coro_value = -(n);; _coro_value = (n))/*這個循環其實僅僅執行兩次 : core_calue == -n 執行子協程和 core_value == n 執行父協程*/ \
            80     if (_coro_value == (n)) \
            81     { \
            82       case -(n): ; \
            83       break; \
            84     } \
            85     else
            86 
            87 #if defined(_MSC_VER)
            88 # define BOOST_ASIO_CORO_YIELD BOOST_ASIO_CORO_YIELD_IMPL(__COUNTER__ + 1)
            89 # define BOOST_ASIO_CORO_FORK BOOST_ASIO_CORO_FORK_IMPL(__COUNTER__ + 1)
            90 #else // defined(_MSC_VER)
            91 # define BOOST_ASIO_CORO_YIELD BOOST_ASIO_CORO_YIELD_IMPL(__LINE__)
            92 # define BOOST_ASIO_CORO_FORK BOOST_ASIO_CORO_FORK_IMPL(__LINE__)
            93 #endif // defined(_MSC_VER)
            94 
            95 #endif // BOOST_ASIO_COROUTINE_HPP
            96 


            posted on 2017-10-14 12:26 Khan 閱讀(1106) 評論(0)  編輯 收藏 引用

            狠狠精品干练久久久无码中文字幕| 手机看片久久高清国产日韩| 久久久老熟女一区二区三区| www.久久精品| 久久综合色之久久综合| 色欲av伊人久久大香线蕉影院| 久久综合丝袜日本网| 婷婷国产天堂久久综合五月| 久久免费视频网站| 三级三级久久三级久久| 国产精品99久久不卡| 一本一道久久综合狠狠老| 国产一区二区精品久久凹凸| 色诱久久久久综合网ywww| 久久播电影网| 精品无码久久久久久尤物| 色青青草原桃花久久综合| 99久久伊人精品综合观看| 久久久噜噜噜久久熟女AA片 | 久久久久久噜噜精品免费直播| 久久精品成人欧美大片| 久久久久亚洲av毛片大| 成人a毛片久久免费播放| 97久久精品无码一区二区| 欧美黑人激情性久久| 亚洲国产精品成人久久蜜臀| 久久久久97国产精华液好用吗| 国产成人久久久精品二区三区| 成人综合伊人五月婷久久| 少妇内射兰兰久久| 精品久久久久久久无码| 一本久道久久综合狠狠爱| 久久亚洲精品无码VA大香大香| 欧美伊人久久大香线蕉综合69| 久久亚洲中文字幕精品一区| 久久av免费天堂小草播放| 久久精品成人一区二区三区| 日韩va亚洲va欧美va久久| 开心久久婷婷综合中文字幕| 国产精品一区二区久久精品涩爱| 久久人人爽人人爽人人片AV高清 |