恢复final_suspend会导致错误,而不会破坏协同程序

时间:2016-11-28 22:04:23

标签: c++ visual-c++ c++-coroutine

James McNellis在他的演讲“C ++ Coroutines简介" (https://youtu.be/ZTqHjjm86Bw?t=1898)说出以下内容:

协程在以下情况下被销毁:

  • final_suspend已恢复,
  • coroutine_handle<> :: destroy()被调用,

先发生者。

在我的测试中,我看到(VS 2015,VS 2017 RC),恢复在final_suspend上暂停的协程会导致错误:

  

Awaits2017.exe中0x010B9EDD处的未处理异常:RangeChecks检测代码检测到超出范围的阵列访问。发生

任何想法可能会在这里发生什么?

#include <experimental/resumable>

using namespace std;
using namespace std::experimental;

struct Coro
{
    coroutine_handle<> m_coro;
    Coro(coroutine_handle<> coro) : m_coro(coro) {}

    struct promise_type
    {
        Coro get_return_object()
        {
            return Coro(coroutine_handle<promise_type>::from_promise(*this));
        }

        auto initial_suspend() { return false; }
        auto final_suspend() { return true; }
        void return_void() {}
    };
};

Coro simple()
{
    co_return;
}

int main()
{
    Coro c = simple();
    c.m_coro.resume(); // runtime error here
}

1 个答案:

答案 0 :(得分:2)

经验法则:

  • 如果login返回final_suspend,则应致电true,而不是coroutine_handle<>::destroy()

  • 如果resume()返回final_suspend,您也不应该调用false,协程会自行清理。

请注意,VS 2015中包含的协程不是James McNellis在视频中显示的(该提案有很多修订版),以及描述:

  

final_suspend已恢复

可能令人困惑。它并不意味着destroy()被调用。