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
