是否有必要在std::coroutine_handle上调用destroy?
的std::coroutine_handle是C ++ 20的新协程的一个重要部分。例如,发电机经常(总是?)使用它。在我见过的所有示例中,在协程的析构函数中手动销毁句柄:
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 Example 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。
回答
这是因为您希望能够让协程比其句柄寿命更长,句柄应该是non-owning。句柄只是一个“视图”,很像std::string_view -> std::string. std::string如果std::string_view超出范围,您不希望自行破坏。
但是,如果您确实想要这种行为,那么围绕它创建自己的包装器将是微不足道的。
话虽如此,该标准规定:
当控制从协程的末尾流出或引用协程的协程句柄
的destroy成员函数
被调用时,协程状态将被破坏。([coroutine.handle.resumption])([coroutine.handle])
协程状态会在运行结束后自行清理,因此不会泄漏,除非控制权没有从最后流出。
当然,在生成器的情况下,控制通常不会流到最后,因此程序员必须手动销毁协程。协程虽然有多种用途,因此标准不能真正无条件地要求句柄析构函数调用destroy()。
THE END
二维码