【发布时间】: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()。
【问题讨论】:
标签: c++ multithreading boost-asio