asio自定义异步函数和c++20协同程序



我正在将我的asio应用程序从它的堆栈式协程迁移到c++20无堆栈协程。我有一个现有的类方法,看起来像这样:

int my_async_op(asio::yield_context yield) {
using tResult = asio::async_result<asio::yield_context, void(boost::system::error_code, int)>;
tResult::completion_handler_type handler(yield);
tResult result(handler);
...
boost::system::error_code ec;
asio::some_async_op(yield[ec]);
...
handler(boost::system::error_code(), 42);
return result.get();
}

并被称为:

boost::system::error_code ec;
x = my_async_op(yield[ec]);

当迁移到C++20无堆栈协程时,需要链接,我的函数骨架现在看起来像这样:

asio::awaitable<int> my_async_op(...) {
...
boost::system::error_code ec;
co_await asio::some_async_op(net::redirect_error(net::use_awaitable, ec));
...
co_return 42;
}

但被称为:

boost::system::error_code ec;
x = co_await my_async_op(net::redirect_error(net::use_awaitable, ec));

因此,骨架需要更新以获得完成令牌,这与本机asio异步操作相同,但我可以找到一个参考示例,我承认发现asio源代码很难解析。

任何指导或参考都将不胜感激。

编辑:我想我已经接近asio::async_initiate perhttp://open-std.org/JTC1/SC22/WG21/docs/papers/2019/p1943r0.html.我的功能现在看起来是这样的:

template<typename T>
auto my_async_op<T&& token) {
return asio::async_initiate<T, void(boost::system::error_code, int)>(
[&](auto handler)->void {
...
boost::system::error_code ec;
co_await asio::some_async_op(asio::redirect_error(asio::use_awaitable, ec));
...
handler(boost::system::error_code(), 42);
},
token
);
}

唯一的问题是,我在嵌套的co-await调用上得到了一个编译器错误:

XXX.h:97:12: error: unable to find the promise type for this coroutine
97 | co_await asio::some_async_op(net::redirect_error(net::use_awaitable, ec));

会一直磨下去。

编辑:正在查看此。。。https://github.com/chriskohlhoff/asio/issues/795

如果您的需求是编写自己的async_xyz函数,则可以使用async_initiate。您应该使用另一个线程在.上运行该函数

我这样做是为了计算提升线程池上的哈希。

例如:

template <boost::asio::completion_token_for<void (std::string)> CompletionToken>
auto
async_hash (boost::asio::thread_pool &pool, boost::asio::io_context &io_context, std::string const &password, CompletionToken &&token)
{
return boost::asio::async_initiate<CompletionToken, void (std::string)> (
[&] (auto completion_handler, std::string const &passwordToHash) {
auto io_eq = boost::asio::prefer (io_context.get_executor (), boost::asio::execution::outstanding_work.tracked);
boost::asio::post (pool, [&, io_eq = std::move (io_eq), completion_handler = std::move (completion_handler), passwordToHash] () mutable {
auto hashedPw = pw_to_hash (passwordToHash);
boost::asio::post (io_eq, [hashedPw = std::move (hashedPw), completion_handler = std::move (completion_handler)] () mutable { completion_handler (hashedPw); });
});
},
token, password);
}

在调用端,您可以像协程中的其他async_xyz函数一样调用它:

auto hashedPw = co_await async_hash (pool, io_context, createAccountObject.password, boost::asio::use_awaitable);

最新更新