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

📄 11.c

📁 在LINUX系统下实现PV操作的算法
💻 C
字号:
#include<unistd.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>#include<sys/types.h>#include<linux/sem.h>#include<linux/shm.h>#define MAX 20   // 定义缓冲区的大小/*定义信号量内部标识*/int emptyid;int fullid;int mutexid;int main(){ printf("***********************************使用pv操作*********************************\n");pv();printf("***********************************无pv操作***********************************\n");no_PV();}int pv(){	int i,C1,C2,p1,p2,m;                     srand(time(NULL));	/*定义P、V操作所用的数据结构*/	struct sembuf P,V;                      /*定义给信号量赋初值的参数数据结构*/	union semun arg;	/*定义共享内存*/	int shmid1,shmid2,shmid3;	int *buffer,*get,*set;                      /*创建信号量并初始化*/	emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);	fullid=semget(IPC_PRIVATE,1,IPC_CREAT|0666);	mutexid=semget(IPC_PRIVATE,1,0666|IPC_CREAT);                      arg.val=1;      /*为信号量赋初值*/	if(semctl(mutexid,0,SETVAL,arg)==-1)		perror("semctl setval error");	arg.val=20;      /*为信号量赋初值*/	if(semctl(emptyid,0,SETVAL,arg)==-1)		perror("semctl setval error");	arg.val=0;	if(semctl(fullid,0,SETVAL,arg)==-1)		perror("semctl setval error");	/*定义信号量的P操作*/	P.sem_num=0;	P.sem_op=-1;	P.sem_flg=0;	/*定义信号量的V操作*/	V.sem_num=0;	V.sem_op=1;	V.sem_flg=0;	/*创建并附接共享内存*/	shmid1=shmget(IPC_PRIVATE,MAX,0666|IPC_CREAT);                       buffer=(int*)shmat(shmid1,0,0);	for( m=1;m<=MAX;m++)	{		buffer[m]=0;	}                           /*创建缓冲区信号量buffer、读缓冲区号的计数get以及写缓冲区号的计数set,并初始化*/	shmid2=shmget(IPC_PRIVATE,MAX,0666|IPC_CREAT);                      set=(int*)shmat(shmid2,0,0);	(*set)=0;	shmid3=shmget(IPC_PRIVATE,MAX,0666|IPC_CREAT);	get=(int*)shmat(shmid3,0,0);	(*get)=0;      while((p1=fork())==-1);		//创建生产者1子进程直到成功为止,p1存放子进程的pid号	   if(p1==0)                   //返回值=0表示子进程返回		{				for(i=0;i<MAX;i++)			 {			     sleep(1);				semop(emptyid,&P,1);	//对emptyid执行P操作				semop(mutexid,&P,1);	//对mutexid执行P操作					if((*set)<MAX)						{							printf("\nP1 put data in No.%d\n",*set);							printf("printf all the data in the buffer :");                                                                                                                                                         buffer[*set]=(rand()%20)+1;							for(m=0;m<MAX;m++)							{      				  			     printf("%d ",buffer[m]);						        }							printf("\n");						}								(*set)++;					semop(mutexid,&V,1);					semop(fullid,&V,1);		//对fullid执行V操作					if((*set)>=20)						break;					}				//sleep(1);				printf("P1 over!\n");				exit(0);	   }		            		 while((p2=fork())==-1);		//创建生产者2子进程直到成功为止,p1存放子进程的pid号		 if(p2==0)                   //返回值=0表示子进程返回			{					for(i=0;i<MAX;i++)				 {					sleep(3);					semop(emptyid,&P,1);	//对emptyid执行P操作					semop(mutexid,&P,1);	//对mutexid执行P操作					if((*set)<MAX)						{							printf("\nP2 put data in No.%d\n",*set);							printf("printf all the data in the buffer :");                                                                                                                                                         buffer[*set]=(rand()%20)+1;							for(m=0;m<MAX;m++)							{      				  			     printf("%d ",buffer[m]);							        }							printf("\n");						}										(*set)++;					semop(mutexid,&V,1);					semop(fullid,&V,1);		//对fullid执行V操作					if((*set)>=20)						break;					}				sleep(1);				printf("P2 over!\n");				exit(0);	   }			while((C1=fork())==-1);		//创建消费者1子进程		if(C1==0)		{			//sleep(5);			for(i=0;i<MAX;i++)			{				//sleep(5);				semop(fullid,&P,1);	//对fullid执行P操作				semop(mutexid,&P,1);				//sleep(1);				if((*get)<MAX)				{					printf("\nC1 get number from No.%d\n",*get);					buffer[*get]=0;					printf("printf all the data in the buffer :");					for( m=0;m<MAX;m++)						printf("%d ",buffer[m]);					printf("\n");				}								(*get)++;				semop(mutexid,&V,1);				semop(emptyid,&V,1);//对emptyid执行V操作				if((*get)>=MAX)					break;						}				printf("C1 over!\n");			exit(0);			}			while((C2=fork())==-1);		//创建消费者2子进程		if(C2==0)		{			//sleep(7);			for(i=0;i<MAX;i++)			{				//sleep(1);				semop(fullid,&P,1);	//对fullid执行P操作				semop(mutexid,&P,1);				//sleep(1);				if((*get)<MAX)				{					printf("\nC2 get number from No.%d\n",*get);					buffer[*get]=0;					printf("printf all the data in the buffer :");					for( m=0;m<MAX;m++)					{						printf("%d ",buffer[m]);					}										printf("\n");				}								(*get)++;				semop(mutexid,&V,1);				semop(emptyid,&V,1);//对emptyid执行V操作				if((*get)>=MAX)					break;						}				printf("C2 over!\n");			exit(0);			}		      wait(0);                           //等待子进程终止	    	      wait(0);		      wait(0);		     				     shmdt(buffer);		 	//断开附接的共享内存                  shmdt(get);			    //断开附接的共享内存                  shmdt(set);			    //断开附接的共享内存	    	     shmctl(shmid1,IPC_RMID,0);	//撤消共享内存和信号量集		     semctl(emptyid,IPC_RMID,0);		     semctl(fullid,IPC_RMID,0);                  semctl(mutexid,IPC_RMID,0);		     wait(0);	 }int no_PV(){     	int i,C1,C2,p1,p2,m;	/*定义P、V操作所用的数据结构*/                      /*定义给信号量赋初值的参数数据结构*/	//union semun arg;	/*定义共享内存*/	int shmid1,shmid2,shmid3;	int *buffer,*get,*set;	//int buffer[MAX];                    	/*创建并附接共享内存*/	shmid1=shmget(IPC_PRIVATE,MAX,0666|IPC_CREAT);                       buffer=(int*)shmat(shmid1,0,0);	for( m=1;m<=MAX;m++)	{		buffer[m]=0;	}                           /*创建缓冲区信号量buffer、读缓冲区号的计数get以及写缓冲区号的计数set,并初始化*/	shmid2=shmget(IPC_PRIVATE,MAX,0666|IPC_CREAT);                      set=(int*)shmat(shmid2,0,0);	(*set)=0;	shmid3=shmget(IPC_PRIVATE,MAX,0666|IPC_CREAT);	get=(int*)shmat(shmid3,0,0);	(*get)=0;      while((p1=fork())==-1);		//创建生产者1子进程直到成功为止,p1存放子进程的pid号	   if(p1==0)                   //返回值=0表示子进程返回		{				for(i=0;i<MAX;i++)			 {			    sleep(1);								if((*set)<MAX)						{							printf("\nP1 put data in No.%d\n",*set);							printf("printf all the data in the buffer :");                                                                                                                                                         buffer[*set]=(rand()%20)+1;							for(m=0;m<MAX;m++)							{      				  			     printf("%d ",buffer[m]);						        }							printf("\n");						}								(*set)++;										if((*set)>=20)						break;					}				//sleep(1);				printf("P1 over!\n");				exit(0);	   }		            		 while((p2=fork())==-1);		//创建生产者2子进程直到成功为止,p1存放子进程的pid号		 if(p2==0)                   //返回值=0表示子进程返回			{					for(i=0;i<MAX;i++)				 {					sleep(3);										if((*set)<MAX)						{							printf("\nP2 put data in No.%d\n",*set);							printf("printf all the data in the buffer :");                                                                                                                                                         buffer[*set]=(rand()%20)+1;							for(m=0;m<MAX;m++)							{      				  			     printf("%d ",buffer[m]);							        }							printf("\n");						}										(*set)++;										if((*set)>=20)						break;					}				//sleep(1);				printf("P2 over!\n");				exit(0);	   }			while((C1=fork())==-1);		//创建消费者1子进程		if(C1==0)		{			//sleep(5);			for(i=0;i<MAX;i++)			{								//sleep(1);				if((*get)<MAX)				{					printf("\nC1 get number from No.%d\n",*get);					buffer[*get]=0;					printf("printf all the data in the buffer :");					for( m=0;m<MAX;m++)						printf("%d ",buffer[m]);					printf("\n");				}								(*get)++;				//semop(mutexid,&V,1);				//semop(emptyid,&V,1);//对emptyid执行V操作				if((*get)>=MAX)					break;						}				printf("C1 over!\n");			exit(0);			}			while((C2=fork())==-1);		//创建消费者2子进程		if(C2==0)		{			//sleep(7);			for(i=0;i<MAX;i++)			{				//sleep(1);								if((*get)<MAX)				{					printf("\nC2 get number from No.%d\n",*get);					buffer[*get]=0;					printf("printf all the data in the buffer :");					for( m=0;m<MAX;m++)					{						printf("%d ",buffer[m]);					}										printf("\n");				}								(*get)++;				//semop(mutexid,&V,1);				//semop(emptyid,&V,1);//对emptyid执行V操作				if((*get)>=MAX)					break;						}				printf("C2 over!\n");			exit(0);			}		      wait(0);                           //等待子进程终止	    	      wait(0);		      wait(0);		     				     shmdt(buffer);		 	//断开附接的共享内存                  shmdt(get);			    //断开附接的共享内存                  shmdt(set);			    //断开附接的共享内存	    	     shmctl(shmid1,IPC_RMID,0);	//撤消共享内存和信号量集		     semctl(emptyid,IPC_RMID,0);		     semctl(fullid,IPC_RMID,0);                  semctl(mutexid,IPC_RMID,0);		     wait(0);	 } 

⌨️ 快捷键说明

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