📄 producer_consummer.cpp
字号:
#include <windows.h>
#include <iostream>
using namespace std;
const unsigned short SIZE_OF_BUFFER = 10; //缓冲区长度
int Buffer_size;//产品出缓冲区时的下标
int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列
bool g_continue = true; //控制程序结束
HANDLE g_hMutex; //用于线程间的互斥
HANDLE g_hFullItems; //缓冲区中被占用的项
HANDLE g_hEmptyItems;
int time=0;//缓冲区中的空项
int count=0;
DWORD WINAPI Producer(LPVOID); //生产者线程
DWORD WINAPI Consumer(LPVOID); //消费者线程
int Thread_ID[100]; //线程号
char Thread_type[100]; //线程类型
int Thread_sleep[100]; //休眠时间
const int PRODUCERS_COUNT = 50; //生产者的个数
const int CONSUMERS_COUNT = 50; //消费者的个数
const int THREADS_COUNT=100; //总的线程数
int Consum_queue[100][100]; //消费者的消费序列
int thread_num;
int last_use=0;
int main()
{
cout<<"输入格式:"<<endl;
cout<<"1)第一行输入缓冲区个数"<<endl;
cout<<"2)后面每行第一个数为线程号,第二个符号为P或C,P代表生产者,C代表消费者,第三个数为进入临界区前的休眠时间;"<<endl;
cout<<"3)如果线程是P,输入以上三个数之后自动结束;"<<endl;
cout<<"4)如果线程是C,输入完以上三个数之后,接着输入消费序列,以0结束;"<<endl;
cout<<"5)最后以0结束输入数据;"<<endl;
cout<<"例如:"<<endl;
cout<<"3"<<endl;
cout<<"1 P 3"<<endl;
cout<<"2 P 4"<<endl;
cout<<"3 C 4 1 0"<<endl;
cout<<"4 P 2"<<endl;
cout<<"5 C 3 1 2 4 0 "<<endl;
cout<<"0"<<endl;
cout<<"输入数据:"<<endl;
//创建各个互斥信号
cin>>Buffer_size;//输入缓冲区大小
g_hMutex = CreateMutex(NULL,FALSE,NULL);
g_hFullItems = CreateSemaphore(NULL,0,Buffer_size,NULL);
g_hEmptyItems = CreateSemaphore(NULL,Buffer_size,Buffer_size,NULL);
HANDLE hThreads[THREADS_COUNT]; //各线程的handle
DWORD producerID[PRODUCERS_COUNT]; //生产者线程的标识符
DWORD consumerID[CONSUMERS_COUNT]; //消费者线程的标识符
//创建生产者线程
//cin>>Buffer_size;//输入缓冲区大小
for (int i = 0; i< Buffer_size;++i){//缓冲区初始化
g_buffer[i] = -1; //当值为-1时该项为空
}
for(int i=1;;i++)
{
thread_num=i;
cin>>Thread_ID[i];
if(Thread_ID[i]==0)break;
cin>>Thread_type[i]>>Thread_sleep[i];
if(Thread_type[i]=='C')
{
for(int j=1;;j++)
{
cin>>Consum_queue[i][j];
if(Consum_queue[i][j]==0){
Consum_queue[i][0]=j-1;
break;
}
}
}
}
for(time=1;time<thread_num;time++)
{
if(Thread_type[time]=='P')//P时创建生产者线程
{
hThreads[time]=CreateThread(NULL,0,Producer,NULL,0,&producerID[time]);
if (hThreads[time]==NULL) return -1;
}
else //C时创建消费者线程
{
hThreads[time]=CreateThread(NULL,0,Consumer,NULL,0,&consumerID[time]);
if (hThreads[time]==NULL) return -1;
}
}
while(g_continue){
if(cin>>count){ //按回车后终止程序运行
g_continue = false;
}
}
return 0;
}
//生产者
DWORD WINAPI Producer(LPVOID lpPara)
{
int s;
s=++count;
int k,flag;
while(g_continue){
flag=0;
Sleep(Thread_sleep[s]*1000);
WaitForSingleObject(g_hEmptyItems,INFINITE);
WaitForSingleObject(g_hMutex,INFINITE);
for(int i=0;i<Buffer_size;i++)
{//检查缓冲区中是否存在当前数
if(g_buffer[i]==s) {
flag=1;
break;
}
}
if(flag==1){//对于缓冲区当中已有的,不用生产
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hFullItems,1,NULL);
continue;
}
else{
for(int i=0;i<Buffer_size;++i)
{
k=i;
if(g_buffer[i]==-1)
{
g_buffer[i]=s;
cout << "线程 "<<s<<" 生产了产品 "<<s<<"。"<<endl;
break;
}
}
if(k+1==Buffer_size&&g_buffer[k]!=s)
{
g_buffer[last_use]=s;
cout << "线程"<<s<<" 生产了产品 "<<s<<"。"<<endl;
}
//输出缓冲区当前的状态
cout<<"缓冲区当前状态:"<<endl;
for (int i=0;i<Buffer_size;++i){
cout << i <<": ";
if (g_buffer[i]==-1)
cout << "null";
else
cout << g_buffer[i];
cout << endl;
}
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hFullItems,1,NULL);
}
}
return 0;
}
//消费者
DWORD WINAPI Consumer(LPVOID lpPara)
{
int s;
s=++count;
int r=1;
while(g_continue){
Sleep(Thread_sleep[s]*1000);
WaitForSingleObject(g_hFullItems,INFINITE);
WaitForSingleObject(g_hMutex,INFINITE);
if(Consum_queue[s][0]==r-1)
{
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hEmptyItems,1,NULL);
cout<<"线程 "<<s<<" 消费完毕!"<<endl;
break;
}
else
{
for(int i=0;i<Buffer_size;i++)
{
if(Consum_queue[s][r]==g_buffer[i]){
r++;
cout << "线程 "<<s<<" 消费了产品 "<<g_buffer[i]<<"。"<<endl;
last_use=i;
//输出缓冲区当前的状态
cout<<"缓冲区当前状态:"<<endl;
for (int i=0;i<Buffer_size;++i){
cout << i <<": ";
if (g_buffer[i]==-1)
cout << "null";
else
cout << g_buffer[i];
cout << endl;
}
break;
}
}
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hEmptyItems,1,NULL);
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -