📄 1.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 + -