【发布时间】:2016-02-01 06:09:10
【问题描述】:
我正在将 asio 用于 tcp 服务器,我也计划将 C++11 std 用于线程。我的最终目标是在 Linux 上拥有此应用程序,但我首先使用 Visual Studio 2015 在 Windows 上对其进行测试。
首先我使用阻塞,所以我发现有关于如何停止等待接受的线程的讨论。有 pre-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() 并且线程到达了join。这是正确的方法吗?
第二种方法“异步”,虽然我还不清楚如何正式停止这个线程,但我成功使用io_service.stop()实际取消了它。
请让我知道我的解决方案是否正确,我会继续尝试不同的解决方案。
【问题讨论】:
-
只使用 std::placeholders::_2 作为第二个占位符?
-
编译好了。所以现在我意识到 asio pdf 中的示例仍然使用 run() 阻止。
-
如果您不想在有外部事件循环的情况下阻塞,您可以使用 run_one 和 poll_one。见stackoverflow.com/questions/8727568/…
-
需要一个比“在这里投诉”更好的错误指示器。
::run()仅在未完成的操作处于提示中时阻塞,除非您创建io_service::work对象。您的问题不清楚,因为您要同时提出 3 个问题。无论如何,手动运行 io_service 所花费的时间与使用::run()的时间一样长,并且您将被阻止。阻塞必须发生在某个地方,最终会发生在::run(),这通常是您指定单独的线程或线程池来运行 io_service 的原因。 -
@Ralf,从名字上看,poll_one 看起来像我需要的那个。我会试试的。
标签: c++ linux multithreading c++11 boost-asio