condition_variable_any类是 std::condition_variable 的泛化。 虽然std::condition_variable 仅适用于 std::unique_lock<std::mutex>,但 condition_variable_any 可以对满足 BasicLockable 要求的任何锁进行操作。
示例
#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 << "\n";
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\n";
return;
}
std::cout << "thread-" << std::this_thread::get_id() << " Xworker goes back to sleep\n";
}
}
int main()
{
unsigned int n = std::thread::hardware_concurrency(); // 当前硬件支持线程并发数
std::cout << n << " concurrent threads are supported.\n";
// 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\n";
return;
}
std::cout << "thread-" << std::this_thread::get_id() << " 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, [&stoken] {
if (stoken.stop_requested()) {
std::cout << "thread-" << std::this_thread::get_id() << " Waiting worker wakeup\n";
return true;
}
else {
std::cout << "thread-" << std::this_thread::get_id() << " Waiting worker sleep...\n";
return false;
}
});
//if (stoken.stop_requested()) {
// std::cout << "thread-" << std::this_thread::get_id() << " Waiting worker is requested to stop\n";
// 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\n";
sleepy_worker.request_stop();
sleepy_worker.join();
std::cout << "Sleepy worker joined\n";
std::this_thread::sleep_for(5s);
// Or automatically using RAII:
// waiting_worker's 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