PSI*_*Alt 13 c++ boost coroutine boost-asio
我正在尝试使用boost::asio::spawn协同程序重写项目.项目的某些部分无法更改.例如,存储协议库也是用boost::asio但没有协同程序编写的.
问题是如何转换yield_context为普通回调(boost::function对象或经典仿函数).
这就是我们在存储库API中的含义:
void async_request_data(uint64_t item_id, boost::function< void(Request_result *) > callback);
Run Code Online (Sandbox Code Playgroud)
正如我们从示例中所知,asio yield上下文可以像这样使用:
my_socket.async_read_some(boost::asio::buffer(data), yield);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,boost::asio::yield_context对象充当async_read_some的回调.我想传递一个yield对象作为第二个参数async_request_data,所以我可以以同步的方式使用它.
如何才能做到这一点?我认为可能通过一些代理对象,可能使用基于asio_handler_invoke的方法.但我很难看到如何做到这一点.
fre*_*fee 13
看起来这个功能的最佳文档可以在boost asio作者编写的C++标准提案中找到:
见9.1节,其中说:
handler_type_t<CompletionToken, void(error_code, size_t)> #3
handler(std::forward<CompletionToken>(token));
Run Code Online (Sandbox Code Playgroud)
3:完成标记被转换为处理程序,即异步操作完成时要调用的函数对象.签名指定将传递给处理程序的参数.
我猜你的情况CompletionToken模板参数实际上是boost::asio::yield_context和handler_type其转换为回调对象.
以下是9.1版中更新的代码,用于调用您的async_request_data函数:
template <class CompletionToken>
auto async_foo(uint64_t item_id, CompletionToken&& token)
{
handler_type_t<CompletionToken, void(Request_result *)>
handler(std::forward<CompletionToken>(token));
async_result<decltype(handler)> result(handler);
async_request_data(item_id, handler);
return result.get();
}
Run Code Online (Sandbox Code Playgroud)
感谢@PSIAlt和@free_coffee,我知道如何在堆栈协程中使用回调函数.
这是一个简单的例子,只为asio新手(像我:D)
https://gist.github.com/chenfengyuan/4d764b0bca82a42c05a9
#include <iostream>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/asio/spawn.hpp>
#include <memory>
void bar(boost::asio::io_service &io, std::function<void()> cb){
auto ptr = std::make_shared<boost::asio::deadline_timer>(io, boost::posix_time::seconds(1));
ptr->async_wait([ptr, cb](const boost::system::error_code&){cb();});
}
template<typename Handler>
void foo(boost::asio::io_service &io, Handler && handler){
typename boost::asio::handler_type<Handler, void()>::type handler_(std::forward<Handler>(handler));
boost::asio::async_result<decltype(handler_)> result(handler_);
bar(io, handler_);
result.get();
return;
}
int main()
{
boost::asio::io_service io;
boost::asio::spawn(io, [&io](boost::asio::yield_context yield){
foo(io, yield);
std::cout << "hello, world!\n";
});
io.run();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3668 次 |
| 最近记录: |