(1)使用互斥锁、C++11条件变量实现简单的生产者消费者模型:
#include <iostream>
#include <mutex> // 互斥锁头文件
#include <thread> // 线程头文件
#include <queue>
#include <condition_variable> // 条件变量头文件
using namespace std;
queue<int> que_; // 互斥访问队列
mutex mtx_; // 互斥锁
condition_variable notEmpty_; // 条件变量,队列不空
condition_variable notFull_; // 条件变量,队列不满
void producer() { // 生产者
for (int i = 0; i < 10; i++) {
unique_lock<mutex> lock(mtx_); // 生产者往队列生产,需要上锁
/*等待队列notFull_(即que_.size() < 10),才可以继续往下执行。
否则释放锁,且阻塞当前线程。直到notFull_被notify时,才被唤醒*/
notFull_.wait(lock, []() { return que_.size() < 10; });
que_.push(i); // 生产一个资源
cout << "生产:" << i << endl;
notEmpty_.notify_one(); // 通知消费者线程队列notEmpty_
this_thread::sleep_for(chrono::milliseconds(50));
}
}
void consumer() { // 消费者
for (int i = 0; i < 10; i++) {
unique_lock<mutex> lock(mtx_); // 消费者从队列消费,需要上锁
/*等待队列notEmpty_(que_.size() > 0),才可继续往下执行。
否则释放锁,且阻塞当前线程。直到notEmpty_被notify时,才被唤醒*/
notEmpty_.wait(lock, []() { return que_.size() > 0; });
cout << "消费:" << que_.front() << endl;
que_.pop(); // 消费一个资源
notFull_.notify_one(); // 通知生产者线程队列notFull_
this_thread::sleep_for(chrono::milliseconds(50));
}
}
void test() {
thread tC(consumer); // 消费者线程
thread tP(producer); // 生产者线程
tP.join(); // 回收生产者线程
tC.join(); // 回收消费者线程
}
执行结果:
(2)使用C++20信号量实现简单的生产者消费者模型
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <semaphore>
using namespace std;
queue<int> que_;
mutex mtx_;
counting_semaphore semEmpty_(5); // 空缺资源数
counting_semaphore semFull_(0); // 可用资源数
void producer() {
for (int i = 0; i < 10; i++) {
semEmpty_.acquire(); // 等待空缺资源
{
lock_guard<mutex> lock(mtx_);
que_.push(i);
cout << "生产了:" << i << endl;
this_thread::sleep_for(chrono::milliseconds(20));
}
semFull_.release(); // 可用资源数+1
}
}
void consumer() {
for (int i = 0; i < 10; i++) {
semFull_.acquire(); // 等待可用资源
{
lock_guard<mutex> lock(mtx_);
cout << "消费了:" << que_.front() << endl;
que_.pop();
this_thread::sleep_for(chrono::milliseconds(20));
}
semEmpty_.release(); // 空缺资源数+1
}
}
void test() {
thread tP(producer);
thread tC(consumer);
tP.join();
tC.join();
}
执行结果: