[英]any elegant way to get c++20 coroutine handle to the outside?
we know that c++20 coroutine suspend and return caller after using co_await awaitable, if we want to resume this coroutine, the only way is to get the coroutine handle from awaitable object function void await_suspend(std::coroutine_handle<> cont) const
and then use handle.resume() to resume coroutine, is there any way to get coroutine handle from the outside of coroutine or any better way to resume coroutine?我们知道c++20协程在使用co_await等待后挂起并返回调用者,如果我们想恢复这个协程,唯一的方法就是从等待的object function
void await_suspend(std::coroutine_handle<> cont) const
然后使用 handle.resume() 来恢复协程,有没有办法从协程外部获取协程句柄或者有更好的方法来恢复协程?
Broadly speaking, you should not want to get the handle from outside of the coroutine machinery.从广义上讲,您不应该希望从协程机器之外获取句柄。 If you do, odds are good that you're not using coroutines in the way they're intended to be used.
如果你这样做了,那么很有可能你没有按照预期的方式使用协程。
The idea of coroutines as designed in C++20 is to be invisible .在 C++20 中设计的协程的想法是不可见的。 That is, from the perspective of code outside of the coroutines nobody should know that it is implemented as a coroutine.
也就是说,从协程之外的代码的角度来看,没有人应该知道它是作为协程实现的。 It is merely a function that returns some type which represents a value that can be obtained in the future;
它只是一个 function 返回某种类型,表示将来可以获得的值; how it pulls this off is an implementation detail.
它如何实现这一点是一个实现细节。
To "resume a coroutine" means to tell the future object returned by a coroutine function to produce the value. “恢复协程”意味着告诉协程 function 返回的未来 object 产生该值。 This should just be a regular API call into the future object.
这应该只是对未来 object 的常规 API 调用。 It is the future object which has access to the promise, and it is the promise which has access to the coroutine handle to resume it.
未来的 object 可以访问 promise,而 promise 可以访问协程句柄来恢复它。
Also, unless the coroutine is a generator, the code which directly resumes the coroutine's execution is intended to be the "awaitable" that the coroutine co_await
ed on.此外,除非协程是生成器,否则直接恢复协程执行的代码旨在成为协程
co_await
上的“等待”。 That is, there's some process that will produce a value, you co_await
on the future that this process returns, and it is that process which will resume your coroutine once the value is ready.也就是说,有一些进程会产生一个值,你
co_await
这个进程返回的未来,一旦值准备好,这个进程将恢复你的协程。 If someone else needs to co_await
on the value your coroutine produces, that's fine.如果其他人需要
co_await
你的协程产生的值,那很好。 Your promise/future machinery will resume them at the completion of your coroutine and give them your promise's value.你的承诺/未来机器将在你的协程完成时恢复它们,并赋予它们你的承诺的价值。
That's how co_await
coroutines are meant to be resumed.这就是
co_await
协程的恢复方式。 Code outside of this process doesn't need a handle and shouldn't get one.此过程之外的代码不需要句柄,也不应该得到句柄。
In any case, unless the promise/future machinery of a coroutine explicitly gives you an API to extract a handle, you can't get a handle.在任何情况下,除非协程的承诺/未来机制明确为您提供 API 来提取句柄,否则您将无法获得句柄。
well, I find a better way to resume coroutine from the caller by reference to c++23 std::generator, shown as below:好吧,我找到了一个更好的方法来通过引用 c++23 std::generator 从调用者恢复协程,如下所示:
struct Result{
//add
Result(promise_type* obj):promise_type_ptr(obj){}
//add
void resume(){
promise_type_ptr->resume();
}
struct promise_type {
// mod
Result get_return_object() {
return Reuslt(this);
}
// add
void resume(){
coroutine_handle<promise_type>::from_promise(*this).resume();
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() {}
suspend_aways yield_value(){}
void return_void() {}
Result return_value(const Result& res){ return res;}
};
// add
promise_type *promise_type_ptr;
};
we can use coroutine_handle<promise_type>::from_promise(*this);
我们可以使用
coroutine_handle<promise_type>::from_promise(*this);
to get coroutine handle from the promise_type object pointer, so we can create a function resume()
in coroutine return result for caller, and use it as below从 promise_type object 指针获取协程句柄,因此我们可以在协程返回结果中为调用者创建一个 function
resume()
,并使用如下
auto result = CoroutineFunction();
result.resume();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.