Boost 1.70 io_service 弃用

Jam*_*rst 2 c++ boost boost-asio c++11

我正在尝试将一些旧代码从使用 io_service 迁移到 io_context 作为基本 tcp 接受器,但是在将 get_io_service() 切换到 get_executor().context() 时遇到问题,导致以下错误:

\n
cannot convert \xe2\x80\x98boost::asio::execution_context\xe2\x80\x99 to \xe2\x80\x98boost::asio::io_context&\xe2\x80\x99\n
Run Code Online (Sandbox Code Playgroud)\n

这是听众:

\n
ImageServerListener::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}\n
Run Code Online (Sandbox Code Playgroud)\n

为了返回 io_context 而不是execution_context,必须更改什么?

\n

seh*_*ehe 5

您将需要关注执行者而不是上下文。

与上下文相反,传递执行器很便宜,它们是可复制的。

此外,它还抽象了执行程序所附加的执行上下文的类型(多态性),因此您无需费心。

然而,执行器的静态类型并不固定。这意味着接受一个的典型方法是通过模板参数:

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)

  • 您是否有机会链接到使用此模型的示例 TCP 端口侦听器/接受器?这个答案我根本不清楚。 (2认同)