C++ Boost Coroutine使用協(xié)程詳解
一、說明語言擴(kuò)展
以下庫擴(kuò)展了編程語言 C++。
- Boost.Coroutine 使得在 C++ 中使用協(xié)程成為可能——其他編程語言通常通過關(guān)鍵字 yield 支持。
- Boost.Foreach 提供了一個(gè)基于范圍的 for 循環(huán),它是在 C++11 中添加到語言中的。
- Boost.Parameter 允許您以名稱/值對(duì)的形式并以任何順序傳遞參數(shù)——例如,這在 Python 中是允許的。
- Boost.Conversion 提供了兩個(gè)轉(zhuǎn)換運(yùn)算符來替換 dynamic_cast 并允許您區(qū)分向下轉(zhuǎn)換和交叉轉(zhuǎn)換。
二、庫Boost.Coroutine
通過 Boost.Coroutine,可以在 C++ 中使用協(xié)程。協(xié)程是其他編程語言的一個(gè)特性,通常使用關(guān)鍵字 yield 來表示協(xié)程。在這些編程語言中,yield 可以像 return 一樣使用。但是,當(dāng)使用 yield 時(shí),該函數(shù)會(huì)記住該位置,如果再次調(diào)用該函數(shù),將從該位置繼續(xù)執(zhí)行。
C++ 沒有定義關(guān)鍵字 yield。但是,使用 Boost.Coroutine 可以從函數(shù)返回并稍后從同一位置繼續(xù)。 Boost.Asio 庫也使用 Boost.Coroutine 并受益于協(xié)程。
三、示例和代碼
Boost.Coroutine 有兩個(gè)版本。本章介紹第二個(gè)版本,即當(dāng)前版本。這個(gè)版本從 Boost 1.55.0 開始可用,并取代了第一個(gè)版本。
示例 51.1。使用協(xié)程
#include <boost/coroutine/all.hpp>
#include <iostream>
using namespace boost::coroutines;
void cooperative(coroutine<void>::push_type &sink)
{
std::cout << "Hello";
sink();
std::cout << "world";
}
int main()
{
coroutine<void>::pull_type source{cooperative};
std::cout << ", ";
source();
std::cout << "!\n";
}示例 51.1 定義了一個(gè)函數(shù) cooperative(),它作為協(xié)程從 main() 調(diào)用。 cooperative() 提前返回 main() 并被第二次調(diào)用。在第二次調(diào)用時(shí),它會(huì)從中斷處繼續(xù)。
要將 cooperative() 用作協(xié)程,使用類型 pull_type 和 push_type。這些類型由 boost::coroutines::coroutine 提供,這是一個(gè)在示例 51.1 中用 void 實(shí)例化的模板。
要使用協(xié)程,您需要 pull_type 和 push_type。其中一種類型將用于創(chuàng)建一個(gè)對(duì)象,該對(duì)象將使用您想用作協(xié)程的函數(shù)進(jìn)行初始化。另一種類型將是協(xié)程函數(shù)的第一個(gè)參數(shù)。
示例 51.1 在 main() 中創(chuàng)建了一個(gè)名為 source 的 pull_type 類型的對(duì)象。 cooperative() 傳遞給構(gòu)造函數(shù)。 push_type 用作 cooperative() 簽名中的唯一參數(shù)。
創(chuàng)建源時(shí),傳遞給構(gòu)造函數(shù)的函數(shù) cooperative() 會(huì)立即作為協(xié)程調(diào)用。發(fā)生這種情況是因?yàn)樵椿?pull_type。如果源基于 push_type,則構(gòu)造函數(shù)不會(huì)將 cooperative() 作為協(xié)程調(diào)用。
cooperative() 將 Hello 寫入標(biāo)準(zhǔn)輸出。之后,函數(shù)像訪問函數(shù)一樣訪問 sink 。這是可能的,因?yàn)?push_type 重載了 operator()。 main() 中的 source 表示協(xié)程 cooperative(),cooperative() 中的 sink 表示函數(shù) main()。調(diào)用 sink 使 cooperative() 返回,而 main() 從調(diào)用 cooperative() 的地方繼續(xù),并將逗號(hào)寫入標(biāo)準(zhǔn)輸出。
然后,main() 調(diào)用 source 就好像它是一個(gè)函數(shù)一樣。同樣,這是可能的,因?yàn)橹剌d了 operator()。這一次,cooperative() 從中斷點(diǎn)繼續(xù)并將世界寫入標(biāo)準(zhǔn)輸出。因?yàn)?cooperative() 中沒有其他代碼,協(xié)程結(jié)束。它返回到 main(),它將一個(gè)感嘆號(hào)寫入標(biāo)準(zhǔn)輸出。
結(jié)果是示例 51.1 顯示 Hello, world!
您可以將協(xié)程視為協(xié)作線程。在某種程度上,函數(shù) main() 和 cooperative() 同時(shí)運(yùn)行。代碼在 main() 和 cooperative() 中輪流執(zhí)行。每個(gè)函數(shù)內(nèi)的指令按順序執(zhí)行。多虧了協(xié)程,一個(gè)函數(shù)不需要在另一個(gè)函數(shù)執(zhí)行之前返回。
示例 51.2。從協(xié)程返回一個(gè)值
#include <boost/coroutine/all.hpp>
#include <functional>
#include <iostream>
using boost::coroutines::coroutine;
void cooperative(coroutine<int>::push_type &sink, int i)
{
int j = i;
sink(++j);
sink(++j);
std::cout << "end\n";
}
int main()
{
using std::placeholders::_1;
coroutine<int>::pull_type source{std::bind(cooperative, _1, 0)};
std::cout << source.get() << '\n';
source();
std::cout << source.get() << '\n';
source();
}示例 51.2 與前面的示例類似。這次模板 boost::coroutines::coroutine 是用 int 實(shí)例化的。這使得從協(xié)程返回一個(gè) int 給調(diào)用者成為可能。
傳遞 int 值的方向取決于使用 pull_type 和 push_type 的位置。該示例使用 pull_type 在 main() 中實(shí)例化一個(gè)對(duì)象。 cooperative() 可以訪問 push_type 類型的對(duì)象。 push_type 發(fā)送一個(gè)值,pull_type 接收一個(gè)值;因此,設(shè)置了數(shù)據(jù)傳輸?shù)姆较颉?/p>
cooperative() 調(diào)用 sink,參數(shù)類型為 int。此參數(shù)是必需的,因?yàn)閰f(xié)程是使用數(shù)據(jù)類型 int 實(shí)例化的。通過使用由 pull_type 提供的成員函數(shù) get() 從 main() 中的 source 接收傳遞給 sink 的值。
示例 51.2 還說明了如何將具有多個(gè)參數(shù)的函數(shù)用作協(xié)程。 cooperative() 有一個(gè)額外的 int 類型參數(shù),不能直接傳遞給 pull_type 的構(gòu)造函數(shù)。該示例使用 std::bind() 將函數(shù)與 pull_type 鏈接起來。
該示例將 1 和 2 后跟 end 寫入標(biāo)準(zhǔn)輸出。
示例 51.3。將兩個(gè)值傳遞給協(xié)程
#include <boost/coroutine/all.hpp>
#include <tuple>
#include <string>
#include <iostream>
using boost::coroutines::coroutine;
void cooperative(coroutine<std::tuple<int, std::string>>::pull_type &source)
{
auto args = source.get();
std::cout << std::get<0>(args) << " " << std::get<1>(args) << '\n';
source();
args = source.get();
std::cout << std::get<0>(args) << " " << std::get<1>(args) << '\n';
}
int main()
{
coroutine<std::tuple<int, std::string>>::push_type sink{cooperative};
sink(std::make_tuple(0, "aaa"));
sink(std::make_tuple(1, "bbb"));
std::cout << "end\n";
}示例 51.3 在 main() 中使用 push_type,在 cooperative() 中使用 pull_type,這意味著數(shù)據(jù)從調(diào)用方傳輸?shù)絽f(xié)程。
此示例說明如何傳遞多個(gè)值。 Boost.Coroutine 不支持傳遞多個(gè)值,因此必須使用元組。您需要將多個(gè)值打包到元組或其他結(jié)構(gòu)中。
示例 51.3 顯示 0 aaa、1 bbb 和 end。
示例 51.4。協(xié)程和異常
#include <boost/coroutine/all.hpp>
#include <stdexcept>
#include <iostream>
using boost::coroutines::coroutine;
void cooperative(coroutine<void>::push_type &sink)
{
sink();
throw std::runtime_error("error");
}
int main()
{
coroutine<void>::pull_type source{cooperative};
try
{
source();
}
catch (const std::runtime_error &e)
{
std::cerr << e.what() << '\n';
}
}協(xié)程在拋出異常時(shí)立即返回。異常被傳輸?shù)絽f(xié)程的調(diào)用者,在那里它可以被捕獲。因此,異常與常規(guī)函數(shù)調(diào)用沒有什么不同。
示例 51.4 顯示了這是如何工作的。此示例會(huì)將字符串錯(cuò)誤寫入標(biāo)準(zhǔn)輸出。
到此這篇關(guān)于C++ Boost Coroutine使用協(xié)程詳解的文章就介紹到這了,更多相關(guān)C++ Boost Coroutine內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)LeetCode(40.組合之和之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(40.組合之和之二),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C語言中多維數(shù)組的內(nèi)存分配和釋放(malloc與free)的方法
寫代碼的時(shí)候會(huì)碰到多維數(shù)組的內(nèi)存分配和釋放問題,在分配和釋放過程中很容易出現(xiàn)錯(cuò)誤。下面貼上一些示例代碼,以供參考。2013-05-05
C語言用函數(shù)指針實(shí)現(xiàn)一個(gè)特別的計(jì)算器
函數(shù)指針是一個(gè)指針變量,它可以存儲(chǔ)函數(shù)的地址,然后使用函數(shù)指針,下面這篇文章主要給大家介紹了關(guān)于C語言用函數(shù)指針實(shí)現(xiàn)計(jì)算器的方法,需要的朋友可以參考下2022-07-07
聊聊Qt+OpenCV聯(lián)合開發(fā)之圖像的創(chuàng)建與賦值問題
這篇文章主要介紹了Qt+OpenCV聯(lián)合開發(fā)之圖像的創(chuàng)建與賦值問題,給大家介紹了圖像的克隆及拷貝問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01
用32位int型變量表示單引號(hào)括起來的四個(gè)字符的深入探討
本篇文章是對(duì)用32位int型變量表示單引號(hào)括起來的四個(gè)字符進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
C++實(shí)現(xiàn)簡單信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡單信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03

