C++ 线程两个问题:
- 线程间的互斥
- 线程间的通信
经典例子 : 生产者与消费者线程模型
#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 对线程的调度是无序的,因此条件变量就控制了这种顺序,并且与互斥锁一同使用。