c++ - 提升继续恢复断言失败
问题描述
我尝试测试继续,我的代码如下
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]进入
DBUG [coepoll.cpp:46] [foo2]进入
INFO [coepoll.cpp:61] [main]在 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 - 它只能使用一次,在调用 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
,程序被中止。
推荐阅读
- javascript - 如何将它包装在 setTimeout 中?如果我们假设从服务器接收数据需要时间(这里只是 txt 文件),所以在一段时间后执行它
- c# - 获取 IEnumerable 的属性
(其中 T 是对象) - autodesk-forge - 在 BIM360 OSS 中为对象创建签名 URL
- qt - Qt 5中具有相同字体点大小的不同实际字体大小
- python - 使用python从验证码图像中删除行
- python - Python计算直到当前行的总计
- c++ - How to put some inputs inside one bitmask? #arduino
- c# - c#UTF8 GetString从字节数组不等于php chr函数
- hibernate - hibernate 如何确保会话缓存或一级缓存使用数据库中的最新数据进行更新?
- java - 以函数式 Java 计算阶乘递归