C++并发多线程--条件变量std::condition_variable的使用

1--std::condition_variable

        std::condition_variable 创建条件变量对象,其可以使用 wait(), notify_one() 等成员函数来实现多线程的条件交互,具体使用方法如下:

#include <iostream>
#include <thread>
#include <mutex>
#include <list>
#include <condition_variable>

class Sample{
public:
    // 模型发送消息
    void inMsgRecvQueue(){
        for(int i = 0; i < 1000; i++){
            std::cout << "Running inMsgRecvQueue(), insert one elem" << i << std::endl;
            std::unique_lock<std::mutex> guard1(mutex1);
            msgRecvQueue.push_back(i);
            // 将wait()所在线程唤醒
            // 假如wait()所在线程正在执行其余代码段,并不处于wait()的状态,此时notify_one()无效果
            cond.notify_one(); 
        }
        return;
    }
    // 模拟取消息
    void outMsgRecvQueue(){
        int command = 0;
        while(true){
            std::unique_lock<std::mutex> guard1(mutex1);
            // wait()用于等待,当lambda表达式返回true时,wait()直接返回
            // 当lambda表达式返回false时,wait()将解锁互斥量,并在本行堵塞
            // 堵塞直到某个线程调用notify_one()成员函数为止
            // 如果wait()没有第二个参数,则与lambda表达式返回false的效果一样
            // 即在本行堵塞,直到某个线程调用notify_one()成员函数
            // 当其他线程用notify_one()堵塞的wait()唤醒后,wait()线程将不断尝试获取锁
            // 当wait()成功获取锁后,将加锁并执行里面的内容(重新判断lambda表达式)
            cond.wait(guard1, [this]{
                if(!msgRecvQueue.empty()) return true;
                else return false;
            });

            // lambda表达式返回true,执行下面的内容
            command = msgRecvQueue.front();
            msgRecvQueue.pop_front();
            guard1.unlock(); // unique_lock可以随时解锁
            std::cout << "Running outMsgRecvQueue(), get one elem: "<< command << std::endl;
            if(command == 999) break; 
        }
    }

private:
    std::mutex mutex1;
    std::list<int> msgRecvQueue;
    std::condition_variable cond;
};

int main(int argc, char *argv[]){
    Sample sample1;
    std::thread OutMsg(&Sample::outMsgRecvQueue, &sample1);
    std::thread InMsg(&Sample::inMsgRecvQueue, &sample1);
    OutMsg.join();
    InMsg.join();
    return 0;
}

2--notify_one()和notify_all()

notify_one() 只能唤醒一个线程,当多个线程都等待被唤醒时,只会随机唤醒一个;

notify_all() 可以同时唤醒多个线程,,当多个线程都会等待被唤醒时,所有线程都会被唤醒;(被唤醒的多个线程可能会竞争同一个互斥锁(假设线程共用一个锁))

猜你喜欢

转载自blog.csdn.net/weixin_43863869/article/details/132360084