gpt4 book ai didi

c++ - co_await 似乎不是最优的?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:30:03 24 4
gpt4 key购买 nike

我有一个异步函数

void async_foo(A& a, B& b, C&c, function<void(X&, Y&)> callback);

我想在无堆栈协程中使用它,所以我写

auto coro_foo(A& a, B& b, C& c, X& x) /* -> Y */ {
struct Awaitable {
bool await_ready() const noexcept { return false; }
bool await_suspend(coroutine_handle<> h) {
async_foo(*a_, *b_, *c_, [this, h](X& x, Y& y){
*x_ = std::move(x);
y_ = std::move(y);
h.resume();
});
}
Y await_resume() {
return std::move(y);
}
A* a_; B* b_; C* c_; X* x_; Y y_;
};
return Awaitable{&a, &b, &c, &x};
}

然后我可以这样使用它:

Y y = co_await coro_foo(a, b, c, x);

编译器会将其重写为:

  auto e = coro_foo(a, b, c, x);
if (!e.await_ready()) {
<suspend>
if (e.await_suspend(h)) return;
resume-point:
<resume>
}
Y y = e.await_resume();

有了这个,协程将在挂起时保留 a_b_c_,此时它只需要保留它们直到我们在await_suspend(h)中获取coroutine_handle
(顺便说一句,我不确定我是否可以在此处保留对参数的引用。)

如果包装函数可以直接获取coroutine_handle作为参数,效率会高很多。

它可能是一个隐式参数:

Promise f(coroutine_handle<> h);
co_await f();

或者它可以是一个特殊的关键字参数:

Promise f(coroutine_handle<> h);
f(co_await);

我是不是漏掉了什么? (其他开销不是那么大。)

最佳答案

Coroutine TS 定义的“协程”系统旨在处理异步功能:

  1. 返回一个类似 future 的对象(一个代表延迟返回值的对象)。
  2. 类 future 对象具有与延续函数关联的能力。

async_foo不满足这些要求。它不会返回类似 future 的对象;它通过延续函数“返回”一个值。并且此延续作为参数传递,而不是您对对象的返回类型执行的操作。

co_await 时发生了,生成 future 的潜在异步过程预计已经开始。或者至少,co_await机械使其可能开始。

您建议的版本在 await_ready 上失败了功能,这是允许 co_await 的原因处理潜在的异步进程。在生成 future 的时间和 await_ready 之间被调用,该过程可能已经完成。如果有,则无需安排协程的恢复。因此,它应该发生在此处,在此线程上。

如果堆栈的低效率问题困扰着您,那么您将不得不按照 Coroutine TS 要求的方式做事。

处理此问题的一般方法是 coro_foo会直接执行async_foo并返回一个类似 future 的对象 .then -样机制。你的问题是 async_foo本身没有 .then -like 机制,所以你必须创建一个。

这意味着 coro_foo必须通过async_foo存储 coroutine_handle<> 的仿函数,一个可以通过 future 的延续机制更新的。当然,您还需要同步原语。如果在执行仿函数时句柄已经初始化,则仿函数调用它,恢复协程。如果仿函数在没有恢复协程的情况下完成,则仿函数将设置一个变量,让等待机器知道该值已准备就绪。

由于句柄和此变量在 await 机制和仿函数之间共享,因此您需要确保两者之间的同步。这是一件相当复杂的事情,但无论如何.then式机械要求。

或者您可以忍受轻微的低效率。

关于c++ - co_await 似乎不是最优的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45311488/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com