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