
安全地取消Boost ASIO Deadline Timer
提供的程式碼旨在在單獨的線程中安全地取消boost::asio:: basic_waitable_timer 。但是,由於潛在問題,取消似乎無法如預期進行。
了解問題:
問題源自於以下事實:所提供的程式碼嘗試使用post函數取消計時器,該函數將取消操作新增至定時器的io_service的事件隊列中。這種方法是有問題的,因為如果在執行取消操作之前計時器已經過期,則取消操作將被忽略,從而有效地使計時器處於活動狀態。
解決問題:
為了解決這個問題,我們需要設計一種強大的方法來取消計時器,無論其當前狀態如何。一種有效的方法是為計時器的到期時間點引入一個哨兵值,該值表示無效狀態。透過在取消過程中將計時器的到期時間設定為該哨兵值,我們可以確保即使在取消先前計時器已到期,也會將其置於無效狀態,從而有效阻止任何進一步的非同步操作。
修改程式碼:
實作哨兵值方法:
1 2 3 4 5 | <code class = "cpp" >timer.get_io_service().post([](){
std::cerr << "tid: " << std::this_thread::get_id() << ", cancelling in post\n" ;
timer.expires_at(Timer::clock_type::time_point::min());
});</code>
|
登入後複製
完成處理程序處理:
在完成處理程序中,檢查哨兵值以檢測關閉:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <code class = "cpp" >void handle_timeout( const boost::system::error_code& ec)
{
if (!ec) {
started = true;
if (timer.expires_at() != Timer::time_point::min()) {
timer.expires_from_now(std::chrono::milliseconds(10));
timer.async_wait(&handle_timeout);
} else {
std::cerr << "handle_timeout: detected shutdown\n" ;
}
}
else if (ec != boost::asio::error::operation_aborted) {
std::cerr << "tid: " << std::this_thread::get_id() << ", handle_timeout error " << ec.message() << "\n" ;
}
}</code>
|
登入後複製
透過哨兵值方法,您現在可以可靠地取消計時器,即使計時器已經過期。
以上是如何在單獨的線程中可靠地取消 Boost ASIO Deadline Timer?的詳細內容。更多資訊請關注PHP中文網其他相關文章!