停止 boost::asio 操作的规范方法
Posted
技术标签:
【中文标题】停止 boost::asio 操作的规范方法【英文标题】:Canonical way to stop boost::asio operations 【发布时间】:2012-10-04 13:03:30 【问题描述】:我有一个boost::asio::io_service
在执行某些操作的线程中运行:
struct clicker
clicker(boost::asio::io_service& io) : timer_(io) wait_for_timer();
void stop() timer_.cancel();
void wait_for_timer()
timer_.expires_from_now(std::chrono::milliseconds(500));
timer_.async_wait(std::bind(&clicker::wait_completed, this, _1));
void wait_completed(const boost::system::error_code& err)
if (!err)
std::cout << "Click" << std::endl;
wait_for_timer();
boost::asio::steady_timer timer_;
;
int main()
boost::asio::io_service io;
clicker cl(io);
std::thread io_thread(&boost::asio::io_service::run, &io);
while (true) // the run loop
// gather input
if (user_clicked_stop_button()) cl.stop(); break;
io_thread.join();
现在调用stop()
应该取消等待计时器并触发wait_completed()
并出现错误。然而,我们这里有一个竞争条件:有时,stop()
将在 wait_for_timer()
运行时和 async_wait
被安排之前被调用。然后,代码将无限期地运行。
处理这种情况的推荐方法是什么?在 wait_completed
中测试的 clicker
中的布尔标志?互斥体?
更新:
这只是一个简化的例子,在实际代码中我有几个操作在io_service
中运行,所以这里不能调用io_service::stop()
。
【问题讨论】:
【参考方案1】:将操作发布到 io_service 线程:
void stop()
timer_.get_io_service().post([=] timer_.cancel(); );
(如果您的编译器不兼容 c++11,请使用 bind
创建 lambda。)
【讨论】:
【参考方案2】:我想你想调用io.stop() 来停止 io_service 对象。
【讨论】:
这只是一个简化的例子。我希望其他操作继续进行。 啊,我错过了。在这种情况下,将取消操作发布到 io_service。 io.post(boost::bind(&clicker::stop, cl));以上是关于停止 boost::asio 操作的规范方法的主要内容,如果未能解决你的问题,请参考以下文章
Boost::asio::async_read 不会在条件下停止
boost::asio::thread_pool - 如何在工作完成前取消工人?