【发布时间】:2018-02-26 04:03:30
【问题描述】:
这是测试用例
#include <boost/coroutine2/all.hpp>
#include <iostream>
#include <cassert>
int main() {
auto sum = 0;
using Coroutine_t = boost::coroutines2::coroutine<int>::push_type;
auto coro = Coroutine_t{[&](auto& yield) {
for (;;) {
auto val = yield.get();
std::cout << "Currently " << val << std::endl;
sum += val;
yield(); // jump back to starting context
}
}};
std::cout << "Transferring 1" << std::endl;
coro(1); // transfer {1} to coroutine-function
std::cout << "Transferring 2" << std::endl;
coro(2); // transfer {1} to coroutine-function
// assert(sum == 3);
}
由于某种原因,最后的断言失败,sum 的值为14 我使用命令安装了 boost(1.63 版)上下文
./bootstrap.sh --prefix=build --with-libraries=context
./b2 --prefix=build --with-context
我在 MacOS 10.12.6 上运行它。编译命令是
g++ -std=c++14 -O3 -I boost co.cpp boost/stage/lib/libboost_*.a
boost 是从 sourceforge 下载的 boost 文件夹。
上面测试用例的输出奇怪的是没有assert是这个
Transferring 1
Currently 0
Transferring 2
Currently 2
Currently 2
为什么在协程中打印第一行Currently 0?另外为什么Currently 2在这里打印两次?后者也可以在这里看到https://wandbox.org/permlink/zEL9fGT5MrzWGgQB
对于第二个问题,似乎在主线程完成后,控制权最后一次转移回协程。这是为什么?这似乎很奇怪..
更新:对于第二个问题,在 boost 1.65 中似乎有所不同??!? https://wandbox.org/permlink/JQa9Wq1jp8kB49Up
【问题讨论】:
-
关于第二个问题。为什么奇怪?有人可能会争辩说,结束协程对象的生命周期应该给例程最后一次运行的机会。
-
@StoryTeller 那么当你有
n协程时会发生什么?即使主线程已经完成,它们是否仍然在 main 之后继续运行?例如,假设从 main 的某个地方抛出异常,在顶层捕获,然后return 1显示错误。但是有很多相互交织的协程在一个点上运行,即使在 main 返回之后,它们是否仍然像一切正常一样继续运行,直到它们达到终止点(如果它们达到终止点)?这看起来很奇怪吧? -
@StoryTeller 它似乎在 boost 1.65 (WOT) 中按预期工作。查看我更新的问题
-
你是说你觉得修复错误很奇怪?
-
@sehe 我不知道这是否是一个错误,这似乎是协程最直接的用例之一,所以我的直觉是这在某种程度上不是一个错误。 .
标签: c++ c++11 boost c++14 boost-coroutine