C++ Thread 条件变量

发布时间 2023-10-04 17:10:12作者: 王清河

Condition_Variable

介绍

  • 条件变量是利用线程间共享的全局变量进行同步的一种机制
  • 条件变量是为了控制多线程有顺序地访问共享资源,它和互斥量协同控制多线程有序,互斥地访问共享资源,重要解决的问题是生产者和消费者的问题

variable_condition

  • 该类是专门结合 unique_lock 使用

variable_condition_any

  • 该类可以搭配任意的一个线程锁使用

函数操作

  1. wait
    • 等待通知
  2. wait_for
    • 等待到收到通知或者超时
  3. notify_one
    • 通知一个等待的线程
  4. notify_all
    • 通知所有的线程

代码

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

std::mutex mtx;
std::condition_variable cv;
bool is_goods = false;

bool judgeGoods()
{
    return is_goods == true;
}

void consumer(int n)
{
    for(int i = 0; i < n; ++i) {
        std::unique_lock<std::mutex> lck(mtx);
        // while (is_goods)
        // {
        //     cv.wait(lck);
        // }
        // consumer can work if there are goods, if no, wait
        cv.wait(lck, []{ return !is_goods;});
        is_goods = true;

        std::cout << "Consumer : " << i << std::endl;
        cv.notify_one();
    }
}

void producer(int n)
{
    for(int i = 0; i < n; ++i) {
        std::unique_lock<std::mutex> lck(mtx);
        // while (!is_goods)
        // {
        //     cv.wait(lck);
        // }
        cv.wait(lck, []{ return is_goods;});
        is_goods = false;

        std::cout << "Producer : " << i << std::endl;
        cv.notify_one();
    }    
}

int main()
{
    std::thread t1(consumer, 10);
    std::thread t2(producer, 10);

    t1.join();
    t2.join();

    return 0;
}

总结

  • 条件变量和互斥锁一起使用主要是用来解决是生产者和消费者的问题,其中使用的步骤如下
  1. 定义互斥锁和条件变量
std::condition_variable cv
std::mutex mtx;
  1. 等待条件满足
std::unique_lock<std::mutex> lck(mtx);
cv.wait(lck, []{ return condition;});
// wait 函数可以接受一个函数,该函数返回 true 表示条件已经满足
// 如果条件不满足,wait() 会释放锁并将线程挂起,直至条件满足
  1. 通知条件满足
cv.notify_one();    // 唤醒一个等待的线程
cv.notify_all();    // 唤醒所有等待的线程