我有一个异步函数co_await似乎不是最理想的?
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_
,此时它只需要保留它们,直到获得coroutine_handle
的await_suspend(h)
。
(顺便说一句,我不知道如果我能保持到参数参考这里)。
这将是更有效的,如果包装函数可直接获得coroutine_handle
作为参数。
这可能是一个隐含参数:
Promise f(coroutine_handle<> h);
co_await f();
或者它可能是一个特殊的关键字参数:
Promise f(coroutine_handle<> h);
f(co_await);
我在这里失去了一些东西? (其它的是,额外开销并不大。)
我的图书馆,concurrencpp,真正处理期货和协程精美,非常优化的方式,检查出来:https://github.com/David-Haim/ concurrencpp –
@DavidHaim,我如何与现有的API使用它像'ASIO :: async_read'或'WSARecv'?顺便说一句,你可能想要更新它,'initial_suspend'不能返回布尔值。 – Abyx
你将不得不编写一个将'concurrencpp :: promise'传递给'boost :: async_xxx'并返回'concurencpp :: future'的包装器。那么你使用常规的'co_await'。 –