Jam*_*rst 2 c++ boost boost-asio c++11
我正在尝试将一些旧代码从使用 io_service 迁移到 io_context 作为基本 tcp 接受器,但是在将 get_io_service() 切换到 get_executor().context() 时遇到问题,导致以下错误:
\ncannot convert \xe2\x80\x98boost::asio::execution_context\xe2\x80\x99 to \xe2\x80\x98boost::asio::io_context&\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\n这是听众:
\nImageServerListener::ImageServerListener(boost::asio::io_context& io)\n{\n _acceptor = new boost::asio::ip::tcp::acceptor(io, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), sConfig.net.imageServerPort));\n StartAccept();\n}\n\nImageServerListener::~ImageServerListener()\n{\n delete _acceptor;\n}\n\nvoid ImageServerListener::StartAccept()\n{\n std::shared_ptr<ImageServerConnection> connection = ImageServerConnection::create(_acceptor->get_executor().context());\n _acceptor->async_accept(connection->socket(), std::bind(&ImageServerListener::HandleAccept, this, connection));\n}\n\nvoid ImageServerListener::HandleAccept(std::shared_ptr<ImageServerConnection> connection)\n{\n connection->Process();\n StartAccept();\n}\nRun Code Online (Sandbox Code Playgroud)\n为了返回 io_context 而不是execution_context,必须更改什么?
\n您将需要关注执行者而不是上下文。
与上下文相反,传递执行器很便宜,它们是可复制的。
此外,它还抽象了执行程序所附加的执行上下文的类型(多态性),因此您无需费心。
然而,执行器的静态类型并不固定。这意味着接受一个的典型方法是通过模板参数:
struct MyThing {
template <typename Executor>
explicit MyThing(Executor ex)
: m_socket(ex)
{ }
void do_stuff(std::string caption) {
post(m_socket.get_executor(),
[=] { std::cout << ("Doing stuff " + caption + "\n") << std::flush; });
}
// ...
private:
tcp::socket m_socket;
};
Run Code Online (Sandbox Code Playgroud)
现在您可以通过多种方式使用它而无需进行任何更改:
int main() {
boost::asio::thread_pool pool;
MyThing a(pool.get_executor());
MyThing b(make_strand(pool));
a.do_stuff("Pool a");
b.do_stuff("Pool b");
boost::asio::io_context ioc;
MyThing c(ioc.get_executor());
MyThing d(make_strand(ioc));
c.do_stuff("IO c");
d.do_stuff("IO d");
pool.join();
ioc.run();
}
Run Code Online (Sandbox Code Playgroud)
这会打印类似的东西
Doing stuff Pool a
Doing stuff Pool b
Doing stuff IO c
Doing stuff IO d
Run Code Online (Sandbox Code Playgroud)
正如您可能已经猜测的那样,内部有类型擦除m_socket来存储执行器。如果您想做同样的事情,您可以使用
boost::asio::any_io_executor ex;
ex = m_socket.get_executor();
Run Code Online (Sandbox Code Playgroud)