いくつ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()
はできません。