C++ 条件变量(condition_variable)

参考链接:https://cloud.tencent.com/developer/article/1584067

参考链接:https://en.cppreference.com/w/cpp/thread/condition_variable

参考链接:https://en.cppreference.com/w/cpp/thread/unique_lock

参考链接:https://en.cppreference.com/w/cpp/thread/condition_variable/wait

unique_lock 一创建就和 lock_guard 类似,就直接阻塞式的lock,lock不到的话就等着。

一出大括号,作用域结束,就unlock。

一旦创建了一个资源,就会尝试唤醒一下cr.wait的人,cr.wait会去阻塞式的lock mtx,lock上了,才退出wait,否则继续等着。

#include <iostream>
#include <thread>
#include <mutex>
#include <queue>
#include <windows.h>
#include <condition_variable>

std::mutex mtx;        // 全局互斥锁
std::queue<int> que;   // 全局消息队列
std::condition_variable cr;   // 全局条件变量
int cnt = 1;           // 数据

void producer() {
    while(true) {
        {
            std::unique_lock<std::mutex> lck(mtx);
            // 在这里也可以加上wait 防止队列堆积  while(que.size() >= MaxSize) que.wait();
            que.push(cnt);
            std::cout << "向队列中添加数据:" << cnt ++ << std::endl;
            // 这里用大括号括起来了 为了避免出现虚假唤醒的情况 所以先unlock 再去唤醒
        }
        cr.notify_all();       // 唤醒所有wait
    }
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lck(mtx);
        while (que.size() == 0) {           // 这里防止出现虚假唤醒  所以在唤醒后再判断一次
            cr.wait(lck);
        }
        int tmp = que.front();
        std::cout << "从队列中取出数据:" << tmp << std::endl;
        que.pop();
    }
}

int main()
{
    std::thread thd1[2], thd2[2];
    for (int i = 0; i < 2; i++) {
        thd1[i] = std::thread(producer);
        thd2[i] = std::thread(consumer);
        thd1[i].join();
        thd2[i].join();
    }
    return 0;
}
文章目录