我有一个 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
中的 bool 标志?互斥体?
更新:
这只是一个简化的示例,在实际代码中,我在 io_service
中运行了多个操作,因此调用 io_service::stop()
不是一个选项.
最佳答案
将操作发布到 io_service 线程:
void stop()
{
timer_.get_io_service().post([=] { timer_.cancel(); });
}
(如果您的编译器不兼容 c++11,请使用 bind
创建 lambda。)
关于c++ - 停止 boost::asio 操作的规范方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12727909/