#include<iostream>
#include<thread>
#include<string>
#include<mutex>
#include<deque>
#include<condition_variable>
#include <windows.h>
using namespace std;
const int NUM = 50; //循环队列大小,实际为49个,另外牺牲一个空间防止判断队列满的时候出现判断错误(假溢出)。
struct DATA
{
int num;
};
struct node {
DATA data[NUM];
int tail;
int front;
int count; //记录队列长度
condition_variable is_not_full; //条件变量不为满
condition_variable is_not_empty;//条件变量不为空
mutex mu;//互斥量保护数据空间防止竞争
}NODE;
typedef struct node node;
bool isFull(node *q) { //判断队列是否为满
if ((q->tail+1)%NUM== q->front)
return true;
else
return false;
}
bool isEmpty(node *q) { //判断队列是否为空
if (q->front == q->tail)
return true;
else
return false;
}
int Length(node *q)
{
return (q->tail - q->front + NUM) % NUM;
}
void produce(node *q,int data) {
unique_lock<mutex> locker(q->mu);
while (isFull(q))//不为满就生产
{
cout << "队列已经满了,等待消费信号" << endl;
q->is_not_full.wait(locker);//等到不为满的条件到来,到来后就往队列里面填充元素
}
q->count += 1;
q->data[q->tail].num = data;
q->tail = (q->tail + 1) % NUM;
cout << "生产项目:" << data << endl;
q->is_not_empty.notify_all();//通知消费
locker.unlock();
}
int consumer(node *q)
{
int data;
unique_lock<mutex> locker(q->mu);
while (isEmpty(q))//不为空就消耗
{
cout << "队列空了,等待生产信号" << endl;
q->is_not_empty.wait(locker);//到来后就是消耗元素,一直阻塞在这里
}
data = q->data[q->front].num;
q->front = (q->front + 1) % NUM;
q->count = q->count - 1;
q->is_not_full.notify_all();//通知生产
locker.unlock();
cout << "消费了:" <<data << endl;
return data;
}
void produce_task() {
for (int i = 1;; i++) //单个无限生产
{
produce(&NODE, i);
}
void consumer_task() { //单个消费
int data;
Sleep(1);
while (1)
{
data = consumer(&NODE);
}
}
void myque_init(node *q)//队列初始化
{
q->count = 0;
q->front = 0;
q->tail = 0;
for (int i = 0; i < NUM; i++)
q->data[i].num = 0;
}
int main()
{
myque_init(&NODE);
std::thread producer(produce_task); // 创建生产者线程.
std::thread consumer(consumer_task); // 创建消费之线程.
producer.join();
consumer.join();
system("pause");
return 0;
}
循环队列示意图: