• <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 閱讀(1069) 評論(0)  編輯 收藏 引用

            精品欧美一区二区三区久久久| 伊人久久综在合线亚洲2019| 亚洲精品成人网久久久久久| 99久久人妻无码精品系列| 青青草国产精品久久| 亚洲色大成网站WWW久久九九| avtt天堂网久久精品| 国产99久久久久久免费看| 国产一区二区精品久久| 色天使久久综合网天天| 一本久久久久久久| 综合久久精品色| 天天久久狠狠色综合| 日韩人妻无码一区二区三区久久99 | 女同久久| 国产精品嫩草影院久久| 久久精品国产亚洲AV蜜臀色欲| 久久久国产99久久国产一| 精品欧美一区二区三区久久久 | 国产精品久久久久久| 2021精品国产综合久久| 久久亚洲熟女cc98cm| 久久精品国产99国产精品| 久久一本综合| 大美女久久久久久j久久| 韩国无遮挡三级久久| 国内精品久久久人妻中文字幕| 亚洲精品无码久久久| 日韩精品无码久久一区二区三| 久久国产综合精品五月天| 国产一久久香蕉国产线看观看| 亚洲中文久久精品无码| 婷婷伊人久久大香线蕉AV| 国产欧美久久一区二区| 国产精品无码久久久久久| 亚洲精品乱码久久久久久蜜桃不卡| 精品国产日韩久久亚洲| 国内高清久久久久久| 久久夜色精品国产欧美乱| 久久久WWW成人免费精品| 久久天天躁狠狠躁夜夜不卡|