使用asio和C ++ 11接受或接收时,优雅地停止线程阻塞或非阻塞

时间:2015-11-01 04:52:04

标签: c++ linux multithreading c++11 boost-asio

我正在为tcp服务器使用asio,我也计划在线程上使用C ++ 11 std。我的最终目标是在Linux上安装此应用程序,但我首先使用Visual Studio 2015在Windows上测试它。

首先我使用阻止,所以我发现有关于如何阻止线程等待接受的讨论。有预先的C ++ 11解决方案,如pipe和select。我正在寻找asio方式。

    asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));
    backAcceptor = &acceptor;
    tcp::socket socket(io_service);

    asio::error_code ec;
    acceptor.accept(socket, &ec);

第二种方法是使用异步,但我更喜欢只使用asio标头。编译抱怨asio :: placeholder没有这个成员但是根据评论,解决方案被应用:

    asio::async_write(socket_, asio::buffer(message_),
        std::bind(&tcp_connection::handle_write, shared_from_this(),
            std::placeholders::_1,
            std::placeholders::_2
            ));

run()仍然阻止那里。我正在寻找从main恢复此线程的方法。

    asio::io_service io_service;
    tcp_server server(io_service);
    io_service.run();

第三种方法是设置超时here。但它并没有阻止我的接受。另外,答案是在2012年。我希望现在有新的解决方案。

更新

为了测试这些场景,我首先有一个线程可以阻塞同步accept()或异步run()。当线程运行时,main等待2秒,并尝试停止线程。然后我等待线程完成使用join。

对于第一种方法" Synchronous",我尝试使用acceptor.cancel()并且线程到达了连接。这是正确的方法吗?

第二种方法" Async",虽然我还不清楚如何正式停止这个线程,但我成功使用io_service.stop()来实际取消它。

请让我知道我的解决方案是否正确,我会继续尝试不同的解决方案。

1 个答案:

答案 0 :(得分:1)

我碰巧使用run_one并且没有线程的非典型方法,特别允许您超时单个“非异步”操作:

实际上,您确实发布了异步操作,但随后超时调用了await_operation

async_connect(socket, ip::tcp::resolver(ioservice).resolve({address, port}), raise());
await_socket(std::chrono::seconds(6));

这相当于执行同步connect ,可能会超时。没有线程,阻塞run()或其他小狗受到伤害。

请参阅演示的链接答案

PS。如果您不希望与deadline_timer

配合使用的posix_time,请high_resolution_timerstd::chrono一起使用