增强继续恢复断言失败

问题描述 投票:0回答:1

我尝试测试延续性,下面是我的代码

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(),导致断言失败。我的代码有错误吗?

c++ boost
1个回答
0
投票

当调用resume时,continuation对象无效。

Reference说:

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. resumeinvalidated上被调用fc1,程序被中止。
© www.soinside.com 2019 - 2024. All rights reserved.