是否有必要在std::coroutine_Handle上调用Destroy?
std::coroutine_handle
是C++20新协程的重要组成部分。例如,生成器经常(Always?)用它吧。在我看到的所有示例中,句柄都是在协例程的析构函数中手动销毁的:
struct Generator {
// Other stuff...
std::coroutine_handle<promise_type> ch;
~Generator() {
if (ch) ch.destroy();
}
}
这真的有必要吗?如果是,为什么coroutine_handle
还没有这样做,有没有RAII版本的coroutine_handle
是这样的,如果我们省略destroy
调用会发生什么?
示例:
- https://en.cppreference.com/w/cpp/coroutine/coroutine_handle(谢谢463035818_is_not_a_number)
- C++20标准在9.5.4.10示例2中也提到了它(在N4892上选中)。
- (德语)https://www.heise.de/developer/artikel/Ein-unendlicher-Datenstrom-dank-Coroutinen-in-C-20-5991142.html
- https://www.scs.stanford.edu/~dm/blog/c++-coroutines.html-提到如果不调用它会泄漏,但没有引用标准中的段落,或者为什么不在
std::coroutine_handle
的析构函数中调用它。
解决方案
这是因为您希望协程比其句柄更长,句柄应该是非所属。句柄只是一个视图,与std::string_view -> std::string
非常相似。如果std::string_view
超出作用域,您不希望std::string
自我销毁。
如果您确实想要此行为,为其创建自己的包装将是微不足道的。
话虽如此,标准specifies:
当控制流出 协程或destroy
成员函数([coroutine.handle.resumption])
协程句柄([coroutine.handle])
,表示调用了协程。
协程状态将在完成运行后自行清理,因此除非控制未流出末尾,否则不会泄漏。
当然,在生成器情况下,控制通常不会流出末尾,因此程序员必须手动销毁协程。但是,协程有多种用途,因此标准不能真正无条件地强制句柄析构函数调用destroy()
。
相关文章