C++ thread 模拟实现的生产者消费者实验。
/**多生产者多消费者**/
/**by Darius**/
#include <bits/stdc++.h>
using namespace std;
const int MaxSize = 4; //仓库大小
const int Plan = 100; //计划生产的产品个数
struct WareHouse
{
int Q[MaxSize]; //缓冲队列
int Front, Rear, cnt_ped, cnt_ced; //队头、队尾、已经生产的数量、已经消费的数量
mutex Mutex, P_mutex, C_mutex; //生产者消费者之间的互斥、生产者之间的互斥、消费者之间的互斥
condition_variable Not_full; //生产者条件变量
condition_variable Not_empty; //消费者条件变量
vector<int> Ready; //准备生产的所有产品的序列
WareHouse() //生成函数
{
memset(Q, 0, sizeof Q); //初始化缓冲队列
cnt_ced = cnt_ped = Front = Rear = 0;
for (int i = 0; i < Plan; ++i) Ready.push_back(i + 1); //初始化产品序列
}
};
static void Producer(WareHouse& Ware_house, int product)
{
unique_lock<mutex> lock(Ware_house.Mutex);
while ((Ware_house.Rear + 1) % MaxSize == Ware_house.Front) //判断队列是否满了,满了需要等待
{
cout << "Warehouse is full, thread " << this_thread::get_id() << " is waiting.
";
Ware_house.Not_full.wait(lock); //等待不满的条件
}
Ware_house.Q[Ware_house.Rear++] = product; //生产产品
Ware_house.Rear %= MaxSize;
cout << "Thread " << this_thread::get_id() << " produced " << product << ", ";
cout << "the count of products : " << (Ware_house.Rear-Ware_house.Front+MaxSize)%MaxSize << endl;
Ware_house.Not_empty.notify_all(); //因为生产了产品,所有队列非空,通知所有消费者
}
static void Consumer(WareHouse& Ware_house)
{
unique_lock<mutex> lock(Ware_house.Mutex);
while (Ware_house.Front == Ware_house.Rear) //判断队列是否为空,空了需要等待
{
cout << "Warehouse is empty, thread " << this_thread::get_id() << " is waiting.
";
Ware_house.Not_empty.wait(lock); //等待非空的条件
}
int product = Ware_house.Q[Ware_house.Front++]; //消费产品
Ware_house.Front %= MaxSize;
cout << "Thread " << this_thread::get_id() << " consumed " << product << ", ";
cout << "the count of products : " << (Ware_house.Rear-Ware_house.Front+MaxSize)%MaxSize << endl;
Ware_house.Not_full.notify_all(); //因为消费了产品,所有队列不满,通知所有生产者
}
int unit_time_P, unit_time_C; //生产者生产单位时间和消费者消费单位时间
static void Run_P(WareHouse& Ware_house)
{
while (true)
{
unique_lock<mutex> lock(Ware_house.P_mutex); //生产者之间的互斥,维护所有生产者生产产品的数量
if (Ware_house.cnt_ped >= Plan) break; //生产完所有产品,任务完成,跳出循环
Producer(Ware_house, Ware_house.Ready[Ware_house.cnt_ped]);
++Ware_house.cnt_ped;
this_thread::sleep_for(chrono::milliseconds(unit_time_P));
}
}
static void Run_C(WareHouse& Ware_house)
{
while (true)
{
unique_lock<mutex> lock(Ware_house.C_mutex); //消费者之间的互斥,维护所有消费者消费产品的数量
if (Ware_house.cnt_ced >= Plan) break; //消费完所有产品,任务完成,跳出循环
++Ware_house.cnt_ced;
Consumer(Ware_house);
this_thread::sleep_for(chrono::milliseconds(unit_time_C));
}
}
int main()
{
cout << "Thread " << this_thread::get_id() << " is MainFunction." <<endl;
cout << "请输入生产者生产单位时间(ms): ";
cin >> unit_time_P;
cout << "请输入消费者消费单位时间(ms): ";
cin >> unit_time_C;
WareHouse W_h;
thread p1(Run_P, ref(W_h)); //创建多个生产者进程
thread p2(Run_P, ref(W_h));
thread p3(Run_P, ref(W_h));
thread c1(Run_C, ref(W_h)); //创建多个消费者进程
thread c2(Run_C, ref(W_h));
thread c3(Run_C, ref(W_h));
p1.join();
p2.join();
p3.join();
c1.join();
c2.join();
c3.join();
return 0;
}