std::jthread::request_stop
來自 cppreference.com
bool request_stop() noexcept; |
(C++20 起) | |
向內部停止狀態發出停止請求,如果尚未請求停止。
該判斷是原子進行的,如果請求停止,則停止狀態會原子更新以避免競態條件,以便
- stop_requested() 和 stop_possible() 可以併發地在同一共享停止狀態的其他 std::stop_token 和 std::stop_source 上呼叫。
- request_stop() 可以從多個執行緒在同一
jthread
物件或與同一停止狀態關聯的其他 std::stop_source 物件上併發呼叫,並且只有一個會實際執行停止請求。
但是,請參閱“備註”部分。
目錄 |
[編輯] 引數
(無)
[編輯] 返回值
如果此呼叫發出了停止請求,則為 true,否則為 false。
[編輯] 後置條件
對於由 get_stop_token() 檢索到的 std::stop_token 或由 get_stop_source() 檢索到的 std::stop_source,stop_requested() 為 true。
[編輯] 備註
如果 request_stop() 確實發出了停止請求(即返回 true),則為同一關聯停止狀態註冊的任何 std::stop_callbacks 將在發出 request_stop() 的同一執行緒上同步呼叫。如果回撥的呼叫透過異常退出,則會呼叫 std::terminate。
如果已經發出了停止請求,則此函式返回 false。但是,不能保證另一個執行緒或 std::stop_source 物件(已成功)請求停止同一停止狀態的執行緒或物件,尚未完成呼叫 std::stop_callback 函式。
如果 request_stop() 確實發出了停止請求(即返回 true),則所有註冊了對與 jthread
內部停止狀態關聯的 std::stop_token 進行可中斷等待的基本型別 std::condition_variable_any 的條件變數都將被喚醒。
[編輯] 示例
執行此程式碼
#include <chrono> #include <condition_variable> #include <iostream> #include <mutex> #include <thread> using namespace std::chrono_literals; // Helper function to quickly show which thread printed what void print(auto txt) { std::cout << std::this_thread::get_id() << ' ' << txt; } int main() { // A sleepy worker thread std::jthread sleepy_worker( [](std::stop_token stoken) { for (int i = 10; i; --i) { std::this_thread::sleep_for(300ms); if (stoken.stop_requested()) { print("Sleepy worker is requested to stop\n"); return; } print("Sleepy worker goes back to sleep\n"); } }); // A waiting worker thread // The condition variable will be awoken by the stop request. std::jthread waiting_worker( [](std::stop_token stoken) { std::mutex mutex; std::unique_lock lock(mutex); std::condition_variable_any().wait(lock, stoken, []{ return false; }); print("Waiting worker is requested to stop\n"); return; }); // Sleep this thread to give threads time to spin std::this_thread::sleep_for(400ms); // std::jthread::request_stop() can be called explicitly: print("Requesting stop of sleepy worker\n"); sleepy_worker.request_stop(); sleepy_worker.join(); print("Sleepy worker joined\n"); // Or automatically using RAII: // waiting_worker's destructor will call request_stop() // and join the thread automatically. }
可能的輸出
140287602706176 Sleepy worker goes back to sleep 140287623300928 Requesting stop of sleepy worker 140287602706176 Sleepy worker is requested to stop 140287623300928 Sleepy worker joined 140287594313472 Waiting worker is requested to stop