我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
调度之前调用。然后,代码将无限期地运行。
处理这种情况的推荐方法是什么?clicker
内部测试的布尔标志wait_completed
?互斥体?
更新:
这只是一个简化的例子,在实际代码中我有几个操作在运行io_service
,所以这里调用io_service::stop()
不是一个选项。