⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 producer_consummer.cpp

📁 应用临界区解决操作系统生产者消费者问题源码
💻 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 + -