C++ 同步通信

C++ 线程两个问题:

  1. 线程间的互斥
  2. 线程间的通信

经典例子 : 生产者与消费者线程模型

#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<unistd.h>
#include<condition_variable>
#include<queue>
#include<thread>
using namespace std;

std::mutex mtx;
std::condition_variable cv;

class Queue {

  public:
    void put(int val) {
      
      unique_lock<std::mutex> lck(mtx);   
      while(!que.empty()) {
        //  当队列不为空时,应该通知消费者去消费了 
        //  因此 wait() 函数 将本线程置于等待状态,并且释放锁
        cv.wait(lck);
      }
      que.push(val);

      // notify_all 通知所有线程,我生产了一个物品,需要消费者消费,因此消费者 就会从等待状态变成 阻塞状态  获取到锁之后可以正常运行
      cv.notify_all();

      cout<<"生产者生成了第"<<val<<"号物品"<<endl;
    }

    int get() {

       unique_lock<std::mutex> lck(mtx);  

      while(que.empty()) {

        
        cv.wait(lck);
        // 当被生产者通知之后,将状态由等待状态变成阻塞状态,当生产者释放锁之后,获取到锁就能正常运行
      }
      
      int val = que.front();
      que.pop();
      cv.notify_all();
      cout<<"消费者消费了第"<<val<<"号物品"<<endl;
      return val;
    }
  private:
    queue<int> que;
};

void producer(Queue * que) {

  for(int i =0; i < 10; i++) {
    que->put(i);
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
  }
}

void consumer(Queue *que) {

  for(int i =0; i < 10; i++) {
    que->get();
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
  }
} 
int main()
{

  Queue que;
  std::thread t1(producer,&que);
  std::thread t2(consumer,&que);
  
  t1.join();
  t2.join();

    cout<<endl;
    return 0;
}

对于一个全局队列,存在一个线程去生产数据,一个线程去消耗数据,那么cpu 对线程的调度是无序的,因此条件变量就控制了这种顺序,并且与互斥锁一同使用。

上一篇:算法整理 & 复习:拓扑排序


下一篇:Python | 面试的常客,经典的生产消费者模式