提升继续恢复断言失败

boost continuation resume Assert failed

本文关键字:断言 失败 恢复 继续      更新时间:2023-10-16

我尝试测试延续,我的代码如下

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;
}

标准输出得到

DBUG [coepoll.cpp:36] [foo1]enter

DBUG [coepoll.cpp:46] [foo2]enter

INFO [coepoll.cpp:61] [main]after callcc

DBUG [coepoll.cpp:38] [foo1]done 1

DBUG [coepoll.cpp:48] [foo2]done 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::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;
}
  1. foo1开始。
  2. 执行返回到main
  3. foo2开始。
  4. 执行返回到main
  5. resumefc1上被调用。fc1无效。控件执行返回到 [6]。
  6. 在恢复foo2的这一行执行中,我们跳转到 [7]。
  7. resume无效fc1调用,程序中止。