我正在为 tcp 服务器使用 asio,我也计划为线程使用 C++11 std。我的最终目标是在 Linux 上运行此应用程序,但我首先使用 Visual Studio 2015 在 Windows 上对其进行测试。
首先我使用阻塞,所以我发现有人讨论如何停止等待接受的线程。有 C++11 之前的解决方案,例如管道和选择。我正在寻找 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 header 。编译提示 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 等待线程完成。
对于第一个方法“同步”,我尝试使用 acceptor.cancel() 并且线程到达了连接。这是正确的方法吗?
第二种方法“异步”,虽然我还不清楚如何正式停止这个线程,但我成功地使用 io_service.stop() 实际取消了它。
请告诉我我的解决方案是否正确,我会继续尝试不同的解决方案。
最佳答案
我碰巧用 run_one
和没有线程的非典型方法玩过,它特别允许您超时个别“非异步”操作:
事实上,您确实发布了异步操作,但随后您调用了带有超时的 await_operation
:
async_connect(socket, ip::tcp::resolver(ioservice).resolve({address, port}), raise());
await_socket(std::chrono::seconds(6));
这相当于同步connect
但是可能会超时。没有线程、阻塞 run()
或其他小狗受到伤害。
查看演示的链接答案
附言。如果您不想要与 std::chrono
配合良好的 high_resolution_timer
,请将 deadline_timer
与 posix_time
一起使用p>
关于c++ - 使用 asio 和 C++11 接受或接收时优雅地停止线程以进行阻塞或非阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33459322/