我尝试测试延续性,下面是我的代码
ctx::continuation fc1;
ctx::continuation fc2;
ctx::continuation foo1(ctx::continuation&& c) {
LOG_DBUG("enter");
c = c.resume();
LOG_DBUG("done 1");
fc2 = fc2.resume();
LOG_DBUG("done 2");
fc2 = fc2.resume();
return std::move(c);
}
ctx::continuation foo2(ctx::continuation&& c) {
LOG_DBUG("enter");
c = c.resume();
LOG_DBUG("done 1");
fc1 = fc1.resume();
LOG_DBUG("done 2");
fc1 = fc1.resume();
return std::move(c);
}
int main() {
fc1 = ctx::callcc(foo1);
fc2 = ctx::callcc(foo2);
LOG_INFO("after callcc");
for (;;) {
while(fc1 = fc1.resume()) LOG_DBUG("main c1");
while(fc2 = fc2.resume()) LOG_DBUG("main c2");
break;
}
std::cout << "main: done" << std::endl;
return 0;
}
stdout得到
DBUG [coepoll.cpp:36] [foo1] enter
DBUG [coepoll.cpp:46] [foo2]输入
INFO [coepoll.cpp:61] [callcc之后的主要]
DBUG [coepoll.cpp:38] [foo1]完成1
DBUG [coepoll.cpp:48] [foo2]完成1
./ myboost / include / boost / context / continuation_fcontext.hpp:263:boost :: context :: continuation boost :: context :: continuation :: resume()&&:断言'nullptr!= fctx_'失败。
似乎在函数foo2
上调用fc1 = fc1.resume()
,导致断言失败。我的代码有错误吗?
当调用resume
时,continuation
对象无效。
continuation是单次连续-只能使用一次,在调用continuation :: resume()或continuation :: resume_with()之后无效。
以下伪代码显示resume
函数的工作方式:
foo(continutation&& mainContext) {
mainContext = mainContext.resume();
// |
// | [2] resume is called;
// | [2] resume invalidates mainContext;
// | [2] no return value is assigned to mainContext!
// | [2] we go back to main
// [4] |
// make assignment |
// now mainContext |
// is valid |
}
int main(){
fooContext = callcc( foo ); // [1] we enter into foo function;
fooContext = fooContext.resume(); // [3] we go back to foo
}
下面是代码的简化版本,让我们对其进行分析:
ctx::continuation foo1(ctx::continuation&& main) {
main = main.resume(); // [2]
fc2 = fc2.resume(); // [6]
fc2 = fc2.resume();
return std::move(c);
}
ctx::continuation foo2(ctx::continuation&& main) {
main = main.resume(); // [4]
fc1 = fc1.resume(); // [7]
fc1 = fc1.resume();
return std::move(c);
}
int main() {
fc1 = ctx::callcc(foo1); // [1]
fc2 = ctx::callcc(foo2); // [3]
for (;;) {
while(fc1 = fc1.resume()) LOG_DBUG("main c1"); // [5]
while(fc2 = fc2.resume()) LOG_DBUG("main c2");
break;
}
foo1
开始。main
。foo2
开始。main
。resume
在fc1
上被调用。 fc1
无效。控制执行返回到[6]。foo2
的这一行中恢复执行,我们跳到[7]。resume
在invalidated上被调用fc1
,程序被中止。