简体   繁体   English

有什么优雅的方法可以让 c++20 协程处理到外部?

[英]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.

相关问题 是否有更优雅的方法使用 c++17/c++20 以“已保存”类型撤消类型擦除? - Is there a more elegant way for undoing type erasure with a "saved" type using c++17/c++20? 在 C++20 中删除协程的复制/移动函数并实例化它是否合法? - Is it legal to delete copy/move functions of a Coroutine in C++20 and instantiate it? 如何用 C++20 协程说 Hello World? - How to say Hello World with C++20 coroutine? 一个C++20协程帧必须预留多少memory? - How much memory must be reserved for a C++20 coroutine frame? 有没有更好的方法在 C++ 20 之前的 C++ 中定义关系运算符? - Is there any better way to define relational operators in C++ pre C++20? Linux 包管理器将如何处理 C++20 模块? - How would Linux package managers handle C++20 modules? C++20:是否有左半范围或右半范围的子范围? - C++20 : Is there any subrange for left or right half range? 默认相等运算符是否有任何 C++20 功能测试? - Is any C++20 feature test for defaulted equal operator? 目前是否有任何编译器支持 C++20? - Do any compilers currently support C++20? 使用 C++20 可以更优雅地读取 N 个输入值吗? - Can the reading of N input values be made more elegant with C++20?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM