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

📄 pv.c

📁 在linux环境下c语言实现生产者消费者问题。多个生产者消费者互斥访问缓冲区
💻 C
字号:
#include <sys/mman.h>#include <sys/types.h>#include <linux/sem.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <errno.h>#include <time.h>#define BUFSIZE 20//声明三个信量int fullid;int emptyid;int mutexid;int main(){   struct sembuf P,V;  union semun arg;  //生成信号量  fullid= semget(IPC_PRIVATE,1,IPC_CREAT|0666);  emptyid=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 =BUFSIZE;  if(semctl(emptyid , 0 ,SETVAL , arg) == -1) perror("semctl setval error");  arg.val = 1;  if(semctl(mutexid , 0 ,SETVAL , arg) == -1) perror("setctl setval error");  //初始化P,V操作  V.sem_num=0;  V.sem_op =1;  V.sem_flg=SEM_UNDO;  P.sem_num=0;  P.sem_op =-1;  P.sem_flg=SEM_UNDO;   //定义共享内存      int shmid;                      int *buffer;     int getid=0,setid=0;     int *get;     int *set;  //创建并附接共享内存    shmid=shmget(IPC_PRIVATE,20*sizeof(int),0666|IPC_CREAT);	buffer=(int*)shmat(shmid,0,0);    setid=shmget(IPC_PRIVATE,sizeof(int),0666|IPC_CREAT);	set=(int*)shmat(setid,0,0);    getid=shmget(IPC_PRIVATE,sizeof(int),0666|IPC_CREAT);	get=(int*)shmat(getid,0,0);  int j=0;  if(fork()==0 )     {      if(fork()>0) //生产者A进程        {          while( (*set) < 30)                {                  semop(emptyid , &P ,1 );                  semop(mutexid , &P , 1);                  buffer[*(set)%BUFSIZE] = (*set)+ 1;                  printf("生产者A放入%d\n", buffer[(*set)%BUFSIZE]);                  printf("当前缓冲区的内容为:");	for(j=0;j<20;j++)	  printf("%d ",buffer[j]);                      printf("\n\n");                  (*set)++;                  semop(mutexid , &V , 1);                  semop(fullid , &V , 1);                  sleep(1);                }                wait(0);//等待子进程终止                wait(0);                wait(0);                shmdt(buffer);//断开附接的共享内存                shmctl(shmid,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);                printf("生产者A进程结束\n");                exit(0);        }      else       //生产者B进程        {                   if(fork()>0)              {                while( (*set) < 30)                  {                    semop(emptyid , &P ,1 );                    semop(mutexid , &P , 1);                    buffer[*(set)%BUFSIZE] = (*set) + 1;                    printf("生产者B放入%d\n", buffer[(*set)%BUFSIZE]);                    printf("当前缓冲区的内容为:");	for(j=0;j<20;j++)	  printf("%d ",buffer[j]);                      printf("\n\n");                    (*set)++;                    semop(mutexid , &V , 1);                    semop(fullid , &V , 1);                    sleep(1);                  }               printf("生产者B进程结束\n");               exit(0);               }            else               {                  if(fork()>0)  //消费者A进程                    {	while(1)	{ 	  semop(fullid , &P , 1);	  semop(mutexid , &P , 1);                        if(*get == 30)                            break;	  printf("消费者A消费%d\n", buffer[(*get)%BUFSIZE] );                        buffer[(*get)%BUFSIZE]=0;                        printf("当前缓冲区的内容为:");	    for(j=0;j<20;j++)	        printf("%d ",buffer[j]);                        printf("\n\n");	  (*get)++;	  semop(mutexid , &V , 1);	  semop(emptyid , &V ,1 );	  sleep(1);	 }                       printf("消费者A进程结束\n");	 exit(0);                    }                      else                          {  //消费者B进程                                 while(1)                                     {                                       semop(fullid , &P , 1);	                 semop(mutexid , &P , 1);                                       if(*get == 30)                                          break;                                       printf("消费者B取出 %d\n",buffer[(*get)%BUFSIZE] );                                        buffer[(*get)%BUFSIZE]=0;                                       printf("当前缓冲区的内容为:");	                 for(j=0;j<20;j++)	                   printf("%d ",buffer[j]);                                       printf("\n\n");	                 (*get)++;	                semop(mutexid , &V , 1);                                      semop(emptyid , &V ,1 );	                sleep(1);	               }                               printf("消费者B进程结束\n");                               exit(0);	                        }                 }            }       }} 

⌨️ 快捷键说明

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