英文:
c++ - How does std::coroutine_handle<>::destroy() work?
问题
可以通过类型擦除的 std::coroutine_handle<>
销毁协程句柄吗?我认为可以,因为相应的代码似乎能够编译。如果可以,那么在底层是如何工作的?编译器/运行时如何知道承诺的实际类型(以便知道调用哪些析构函数)?
英文:
Is it okay to destroy a coroutine-handle via a type-erased std::coroutine_handle<>
? I assume it is, because corresponding code seems to compile. If so, how does this work under the hood? How does the compiler/runtime know what the actual type of the promise is (so that it knows which destructors to call)?
答案1
得分: 2
是的,这样做完全没问题。std::coroutine_handle<>
被设计成可以作为类型擦除的句柄正常工作。仅在需要访问协程的 promise 对象时才需要明确指定 promise 类型。
至于协程句柄如何知道如何销毁 promise……事实上,它并不知道。这一切都由协程状态对象管理(协程句柄指向的对象)。协程状态负责管理 promise 对象,还负责管理协程体的局部变量以及跟踪当前的挂起点。具体的细节都是由实现定义的。
一个擦除类型的协程句柄如何调用给定协程状态的适当 destroy
函数的示例是通过在协程帧上间接调用存储在其中的函数指针,这是 clang 根据其文档的情况。
‘llvm.coro.destroy’ 内部函数销毁一个挂起的切换-恢复协程。
[..] 在可能的情况下,coro.destroy 内部函数会被直接调用协程销毁函数替代。否则,它将根据存储在协程帧中的销毁函数的函数指针进行间接调用。
英文:
Yes it is perfectly ok to do that. std::coroutine_handle<>
is designed to work just fine as a type erased handle. The only use for explicitly specifying the promise type is when you need to access the promise object of the coroutine.
As for how the coroutine handle knows how to destroy the promise... well it doesn't. It's all managed by the coroutine state object (that the coroutine handle points to). The coroutine state is responsible for managing, not only the promise object, but also any local variables of the coroutine body as well as keep track of the current suspension point. The actual details are all implementation defined.
An example of how can a type-erased coroutine handle invoke the appropriate destroy
function for a given coroutine state, is to call it indirectly through a function pointer stored on the coroutine frame, which is the case with clang according to its docs
> The ‘llvm.coro.destroy’ intrinsic destroys a suspended switched-resume coroutine.
>
> [..] when possible, the coro.destroy intrinsic is replaced with a direct call to the coroutine destroy function. Otherwise it is replaced with an indirect call based on the function pointer for the destroy function stored in the coroutine frame.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论