当使用asio和C++11接受或接收时,优雅地停止线程进行阻塞或非阻塞
Elegantly stop the thread for blocking or non-blocking when accept or receive using asio and C++11
我正在为tcp服务器使用asio,并计划为线程使用C++11 std。我的最终目标是在Linux上拥有这个应用程序,但我首先使用Visual Studio 2015在Windows上测试它。
首先我使用了阻塞,所以我发现有人在讨论如何停止线程等待accept。有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::占位符没有这个成员,但根据评论,应用了解决方案:
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();
第三种方法是,在这里设置一个超时。但这并没有阻止我接受。另外,答案是在2012年。我希望现在有新的方法来解决这个问题。
更新
为了测试这些场景,我首先让一个线程在同步accept()或异步run()处阻塞。当线程正在运行时,main会等待2秒钟,并尝试停止线程。然后我使用join等待线程完成。
对于第一个方法"Synchronous",我尝试使用receiver.cancel(),线程到达连接。这是正确的方法吗?
第二个方法"Async",尽管我仍然不清楚如何正式停止这个线程,但我成功地使用io_service.stop()来实际取消它。
请让我知道我的解决方案是否正确,我将继续尝试不同的解决方案。
我碰巧用了一种不典型的run_one
方法,没有线程,它特别允许您超时单个"非异步"操作:
- boost::asio+std::future-关闭套接字后发生访问冲突
事实上,您确实发布了异步操作,但随后您调用了带有超时的await_operation
:
async_connect(socket, ip::tcp::resolver(ioservice).resolve({address, port}), raise());
await_socket(std::chrono::seconds(6));
这相当于执行同步connect
,但可能会超时。没有螺纹、堵塞run()
或其他幼犬受到伤害。
查看演示的链接答案
PS。如果您不想要与std::chrono
配合良好的high_resolution_timer
,请将deadline_timer
与posix_time
配合使用
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 提升 ASIO - io_service 不要等待连接到线程
- ASIO signal_set多个 IO 线程不可靠,具体取决于代码顺序?
- 将更高的优先级设置为 boost::asio 线程处理进程
- asio 链对象线程安全吗?
- asio::io_service 具有多个线程的优先级队列处理
- boost信号和插槽在不同的线程中不工作(使用boost::asio::io_service)
- 调用boost.asio的异步函数时,线程是什么时候创建的
- 调用socket.remote_endpoint(提升 asio 库)线程安全性
- 使用线程池提升 ASIO 多线程 TCP 服务器
- 重写多线程事件驱动的C 程序以使用单线程Boost :: Asio
- 在具有许多内核的计算机上,使用 Boost ASIO 只能使用 1 个线程
- 如何将每线程用户数据传递到ASIO处理程序中
- 提高 ASIO stream_descriptor和事件 FD 线程安全性
- 提升 asio io_service多线程性能不佳
- 在std ::线程中升级ASIO阻止操作,而不是使用异步方法
- 是boost :: asio :: thread_pool线程在多个线程上发布任务时的安全性
- Boost.Asio、tcp::iostream 和多线程
- Boost.Asio:由于线程退出或应用程序请求,I/O 操作已中止
- boost::asio绞线缠绕的线程无法立即工作