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