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

📄 1.c

📁 C语言PV操作实现两个生产者两个消费者
💻 C
字号:
#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<time.h>#include<errno.h>#include<sys/types.h>#include<linux/sem.h>#include<linux/shm.h>#define MAXSHM 20/*定义信号量内部标识*/int emptyid;int fullid;int mutexid;main(){	int arrayid;	int getid;	int setid;		// 三个共享内存ID	int *array;	int *get;	int *set;		//共享内存虚拟地址	arrayid=shmget(IPC_PRIVATE,sizeof(int)*MAXSHM,IPC_CREAT|0666);	getid=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666);	setid=shmget(IPC_PRIVATE,sizeof(int),IPC_CREAT|0666);//创建共享内存	array=(int *)shmat(arrayid,0,0);	get=(int *)shmat(getid,0,0);	set=(int *)shmat(setid,0,0);	*get=0;	*set=0;//初始化共享内存	/*定义信号量数据结构*/	struct sembuf P,V;	union semun arg;	/*创建信号量并初始化*/	emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);	fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);	mutexid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);	arg.val=0;		//初始时缓冲区中无数据	if(semctl(fullid,0,SETVAL,arg)==-1)		perror("semctl setval error");	arg.val=MAXSHM;		//初始时缓冲区中有5个空闲的数组元素	if(semctl(emptyid,0,SETVAL,arg)==-1)		perror("semctl setval error");	arg.val=1;			//初始时互斥信号为1,允许一个进程进入	if(semctl(mutexid,0,SETVAL,arg)==-1)		perror("semctl setval error");	/*定义P、V操作*/	P.sem_num=0;	P.sem_op=-1;	P.sem_flg=SEM_UNDO;	V.sem_num=0;	V.sem_op=1;	V.sem_flg=SEM_UNDO;	int i;	/****生产者A****/	if(fork()==0)	{		while((*set)<20)		{			semop(emptyid,&P,1);                        		semop(mutexid,&P,1);//对mutexid执行P操作			array[(*set)%MAXSHM]=*set+1;			printf("ProducerA put number %d to NO. %d\n",array[(*set)%MAXSHM],((((*set)+1)%MAXSHM)==0?20:((*set)+1)%MAXSHM));			i=0;			while(i<20)			{printf("%d--",array[i]);i++;}printf("\n\n");		//显示当前共享区使用情况			(*set)++;		//写计数加1			semop(mutexid,&V,1);	//对mutexid执行V操作			semop(fullid,&V,1);	//对fullid执行V操作			sleep(1);		}		sleep(2);		printf("ProducerA is over\n");		exit(0);	}	else	{			/****生产者B****/		if(fork()==0)		{			while((*set)<20)			{				semop(emptyid,&P,1);	//对emptyid执行P操作				semop(mutexid,&P,1);	//对mutexid执行P操作				array[(*set)%MAXSHM]=*set+1;					printf("ProducerB put number %d to NO. %d\n",array[(*set)%MAXSHM],((((*set)+1)%MAXSHM)==0?20:((*set)+1)%MAXSHM));				i=0;				while(i<20)				{printf("%d--",array[i]);i++;}printf("\n\n");		//显示当前共享区使用情况				(*set)++;//写计数加1				semop(mutexid,&V,1);	//对mutexid执行V操作				semop(fullid,&V,1);	//对fullid执行V操作				sleep(1);			}			sleep(2);			printf("ProducerB is over\n");			exit(0);		}		else					/****消费者A****/			if(fork()==0)			{				while(1)				{					if(*get==20) break;					semop(fullid,&P,1);	//对fullid执行P操作					semop(mutexid,&P,1);	//对mutexid执行P操作					printf("The ConsumerA get number %d from NO. %d\n",array[(*get)%MAXSHM],((((*get)+1)%MAXSHM)==0?20:(((*get)+1)%MAXSHM)));					array[(*get)%MAXSHM]=0;					i=0;					while(i<20)					{printf("%d--",array[i]);i++;}printf("\n\n");		//显示当前共享区使用情况					(*get)++;			//读计数加1					semop(mutexid,&V,1);	//对mutexid执行V操作					semop(emptyid,&V,1);	//对emptyid执行V操作					sleep(1);				}				printf("ConsumerA is over\n");				exit(0);			}			else			{				/****消费者B****/				if(fork()==0)				{					while(1)					{						if(*get==20) break;						semop(fullid,&P,1);	//对fullid执行P操作						semop(mutexid,&P,1);	//对mutexid执行P操作						printf("The ConsumerB get number %d from NO. %d\n",array[(*get)%MAXSHM],((((*get)+1)%MAXSHM)==0?20:(((*get)+1)%MAXSHM)));						array[(*get)%MAXSHM]=0;						i=0;						while(i<20)						{printf("%d--",array[i]);i++;}printf("\n\n");		//显示当前共享区使用情况						(*get)++;			//读计数加1						semop(mutexid,&V,1);	//对mutexid执行V操作						semop(emptyid,&V,1);	//对emptyid执行V操作						sleep(1);					}					printf("ConsumerB is over\n");					exit(0);				}			}		}/****父进程返回后回收4个子进程****/wait(0);wait(0);wait(0);wait(0);/****断开并撤销3个共享内存****/shmdt(array);shmctl(arrayid,IPC_RMID,0);shmdt(get);shmctl(getid,IPC_RMID,0);shmdt(set);shmctl(setid,IPC_RMID,0);/***撤销三个信号量集***/semctl(emptyid,IPC_RMID,0);semctl(fullid,IPC_RMID,0);semctl(mutexid,IPC_RMID,0);exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -