condition_variable 的使用信号量mutex,多线程
condition_variable
是 C++11 中的一个线程库类,用于实现线程间的同步和通信。condition_variable 可以与 unique_lock 或 lock_guard 一起使用,用于实现线程的等待和唤醒操作。condition_variable 的主要作用是在多个线程之间同步共享资源的访问,以避免资源的竞争和冲突。
1、condition_variable 类的函数 wait()
cv.wait() 函数将当前线程阻塞,等待condition_variable 唤醒
2、condition_variable 类的函数 wait_for()
wait_for() 函数中,第一个参数是 unique_lock 对象,第二个参数是等待的时间,第三个参数是一个可调用对象,用于检查条件变量是否满足。
3、condition_variable 类的函数 wait_until()
wait_until() 函数中,第一个参数是 unique_lock 对象,第二个参数是等待的时间点,第三个参数是一个可调用对象,用于检查条件变量是否满足。
4、condition_variable 类的函数notify_one 和 notify_all
notify_one 通知等待的一个线程,如果有多个,无法准确通知是哪一个,需要自行加代码判断
notify_all 通知等待的所以线程
代码用例
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
mutex mtx;
condition_variable cv;
bool ready = false;
void worker_thread() {
unique_lock<mutex> lck(mtx);
while (!ready) {
cout << "worker_thread wair" << endl;
// 等待 cv 通知,通知了就执行
cv.wait(lck);
}
cout << "Worker thread is running." << endl;
}
void worker_thread_1() {
unique_lock<mutex> lck(mtx);
//wait_for() 成员函数等待一段时间,如果在指定时间内条件变量仍未满足,则返回 false。在 wait_for() 函数中,
// 第一个参数是 unique_lock 对象,第二个参数是等待的时间,第三个参数是一个可调用对象,用于检查条件变量是否满足。
// 等待 cv 通知,如果1秒后cv 还没有通知就执行后面函数并解锁
while (!cv.wait_for(lck, chrono::seconds(1), []{ return ready ; })) {
cout << "worker_thread_1 wair" << endl;
}
cout << "Worker1 thread is running." << endl;
}
void worker_thread_2() {
unique_lock<mutex> lck(mtx);
chrono::steady_clock::time_point tp = chrono::steady_clock::now() + chrono::seconds(1);
//wait_until() 成员函数等待指定时间点,如果在指定时间点前条件变量仍未满足,则返回 false。在 wait_until() 函数中,
// 第一个参数是 unique_lock 对象,第二个参数是等待的时间点,第三个参数是一个可调用对象,用于检查条件变量是否满足。
// 等待 cv 通知,如果1秒后这个时间点cv 还没有通知就执行后面函数并解锁;打印一次后,如果还没与通知再等1秒,依次下去
if (!cv.wait_until(lck, tp, []{ return ready ; })) {
cout << "worker_thread_2 wair" << endl;
}
cout << "Worker2 thread is running." << endl;
}
int main() {
thread worker(worker_thread);
thread worker1(worker_thread_1);
thread worker2(worker_thread_2);
cout << "Main thread is waiting." << endl;
this_thread::sleep_for(chrono::seconds(3));
{
lock_guard<mutex> lck(mtx);
ready = true;
cv.notify_one();
cv.notify_one();
cv.notify_one();
}
worker.join();
worker1.join();
worker2.join();
return 0;
}
执行的结果
Main thread is waiting.
worker_thread wair
worker_thread_1 wair
worker_thread_2 wair
Worker2 thread is running.
worker_thread_1 wair
Worker1 thread is running.
Worker thread is running.