C++ condition_variable 實現生產者消費者模型
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <queue>
#include<windows.h>
#include<chrono>
using namespace std;
using namespace std::chrono;
#define PRODUCE_TIME 1000 // 生產 時間 ms
#define CONSUME_TIME 1000 // 消費 時間 ms
#define MAX_SIZE 5 // 緩衝區 儲存容量
#define STOP_FLAG 10 // 結束標誌 消費10個產品 程式結束
int stopflag = 0;
// 緩衝區
mutex bufferMutex;
queue<int> buffer;
int productID = 0;
// 輸出 鎖
mutex printMutex;
mutex NoEmpty;
mutex NoFull;
// 條件變數
condition_variable bufferNoEmpty;
condition_variable bufferNoFull;
void GetTime()
{
system_clock::duration d = system_clock::now().time_since_epoch();
milliseconds mil = duration_cast<milliseconds>(d);
cout << mil.count() << "毫秒 == ";
}
void Producer()
{
while (1)
{
Sleep(PRODUCE_TIME); // 花時間生產
unique_lock<mutex> lk(NoFull);
while (buffer.size() == MAX_SIZE) // 滿
{
printMutex.lock();
GetTime();
cout << " 緩衝區滿了..." << endl;
printMutex.unlock();
// 空閒數 0 需等待
if (stopflag >= STOP_FLAG)
{
printMutex.lock();
GetTime();
cout << "已取出限定個數" << endl;
printMutex.unlock();
break;
}
bufferNoFull.wait(lk);
}
if (stopflag >= STOP_FLAG)
{
break;
}
printMutex.lock();
GetTime();
cout << "放入 : " << productID << endl;
buffer.push(productID++);
printMutex.unlock();
if (buffer.size() >= 1)
{
bufferNoEmpty.notify_all();
}
if (stopflag >= STOP_FLAG)
{
break;
}
}
printMutex.lock();
GetTime();
cout << "結束生產 " << endl;
printMutex.unlock();
}
void Consumer()
{
while (1)
{
unique_lock<mutex> lk(NoEmpty);
while (buffer.empty())
{
printMutex.lock();
GetTime();
cout << "緩衝區空了..." << endl;
printMutex.unlock();
bufferNoEmpty.wait(lk); // 當前 無產品 需要等待生產
}
int product = -1;
printMutex.lock();
product = buffer.front();
buffer.pop();
GetTime();
cout << "取出 : " << product << endl;
printMutex.unlock();
if (buffer.size() < MAX_SIZE)
{
bufferNoFull.notify_all(); // 通知 有空閒位置
}
Sleep(CONSUME_TIME); // 消費產品
stopflag++;
if (stopflag >= STOP_FLAG)
{
break;
}
}
printMutex.lock();
GetTime();
cout << "結束消費 " << endl;
printMutex.unlock();
bufferNoFull.notify_all(); // 通知 生產者 不需要再等待
}
int main()
{
thread Produce(Producer);
thread Consume(Consumer);
//getchar();
Produce.join();
Consume.join();
//getchar();
lock_guard<mutex> lock(bufferMutex);
cout << "buffer 剩下個數:" << buffer.size() << endl;
cout << "下一個生產id: " << productID << endl;
return 0;
}