C++多线程-stop_stop_token-condition_variable_any
类是 std::condition_variable 的泛化。 虽然std::condition_variable 仅适用于 std::unique_lock<std::mutex>,但 condition_variable_any 可以对满足 要求的任何锁进行操作。
示例
#include <iostream> #include <thread> #include <chrono> #include <mutex> #include <condition_variable> using namespace std::chrono_literals; void Xworker(std::stop_token stoken, int argX) { std::cout << "thread-" << std::this_thread::get_id() << " argX = " << argX << " "; while (true) { std::this_thread::sleep_for(1s); if (stoken.stop_requested()) { std::cout << "thread-" << std::this_thread::get_id() << " Xworker is requested to stop "; return; } std::cout << "thread-" << std::this_thread::get_id() << " Xworker goes back to sleep "; } } int main() { unsigned int n = std::thread::hardware_concurrency(); // 当前硬件支持线程并发数 std::cout << n << " concurrent threads are supported. "; // A sleepy worker thread std::jthread sleepy_worker([](std::stop_token stoken) { // for (int i = 10; i; --i) { while (true) { std::this_thread::sleep_for(100ms); if (stoken.stop_requested()) { std::cout << "thread-" << std::this_thread::get_id() << " Sleepy worker is requested to stop "; return; } std::cout << "thread-" << std::this_thread::get_id() << " Sleepy worker goes back to sleep "; } }); // 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, [&stoken] { if (stoken.stop_requested()) { std::cout << "thread-" << std::this_thread::get_id() << " Waiting worker wakeup "; return true; } else { std::cout << "thread-" << std::this_thread::get_id() << " Waiting worker sleep... "; return false; } }); //if (stoken.stop_requested()) { // std::cout << "thread-" << std::this_thread::get_id() << " Waiting worker is requested to stop "; // return; //} }); std::jthread xworker(Xworker, 2); // std::jthread::request_stop() can be called explicitly: std::this_thread::sleep_for(1s); std::cout << "Requesting stop of sleepy worker "; sleepy_worker.request_stop(); sleepy_worker.join(); std::cout << "Sleepy worker joined "; std::this_thread::sleep_for(5s); // Or automatically using RAII: // waiting_workers destructor will call request_stop() // and join the thread automatically. }
运行结果
16 concurrent threads are supported. thread-1616 argX = 2 thread-2248 Waiting worker sleep... thread-24232 Sleepy worker goes back to sleep thread-24232 Sleepy worker goes back to sleep thread-24232 Sleepy worker goes back to sleep thread-24232 Sleepy worker goes back to sleep thread-24232 Sleepy worker goes back to sleep thread-24232 Sleepy worker goes back to sleep thread-24232 Sleepy worker goes back to sleep thread-24232 Sleepy worker goes back to sleep thread-24232 Sleepy worker goes back to sleep Requesting stop of sleepy worker thread-1616 Xworker goes back to sleep thread-24232 Sleepy worker is requested to stop Sleepy worker joined thread-1616 Xworker goes back to sleep thread-1616 Xworker goes back to sleep thread-1616 Xworker goes back to sleep thread-1616 Xworker goes back to sleep thread-1616 Xworker goes back to sleep thread-1616 Xworker is requested to stop thread-2248 Waiting worker wakeup