condition_variable 的使用信号量mutex,多线程

发布时间 2023-12-07 18:15:06作者: 水三丫

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.