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