资源预览内容
第1页 / 共5页
第2页 / 共5页
第3页 / 共5页
第4页 / 共5页
第5页 / 共5页
亲,该文档总共5页全部预览完了,如果喜欢就下载吧!
资源描述
实验二 Linux 进程同步与通信【关键问题】一个生产者向一个缓冲区发消息,每当发出一个消息后,要等待三个消费者都接收这条消息后,生产者才能发送新消息。用信号量和P、V操作,写出他们同步工作的程序。【设计思路】首先声明 7 个信号灯 ID,他们分别是 full1,full2,full3,empty1,empty2,empty3,mutxid;用函数mmap()创建虚拟主存区array,brray,set,get,bet;初始化变量get,set,bet;通过函数semget()分 别 创 建 各 信 号 量 full1,full2,full3,empty1,empty2,empty3,mutxid,并 用 函 数semctl()为各信号量赋初值full1=1,full2=1,full3=1,empty1=0,empty2=0,empty3=0,mutxid=1;然后初始化 P,V 操作;在主函数中创建一个生产者进程,在创建三个消费者进程;通过P,V 操作,生产者进程向缓冲区发送一个消息(三个数据),当三个消费者进程都接受到这条消息时,生产者才能再次先缓冲区从新发送消息,如此循环。【关键代码】#include#include#include#include#include#include#include#include#define MAXSEM 1/声明三个信号灯 ID int full1;int full2;int full3;int empty1;int empty2;int empty3;int mutxid;int main()struct sembuf P,V;/对信号量操作时需要的数据结构union semun arg;/对信号量操作时需要的数据结构/声明虚拟主存int *array;int *brray;int *set;名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 5 页 -int *get;int *bet;/创建虚拟主存。即变量作为共享虚拟主存实现。array =(int *)mmap(NULL,sizeof(int )*MAXSEM,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);get=(int *)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);set=(int *)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);bet=(int *)mmap(NULL,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);/初始化变量 *get=0;*bet=0;*set=0;/创建信号量 full1=semget(IPC_PRIVATE,1,IPC_CREAT|00666);/该信号量用于消费者获取数据 full2=semget(IPC_PRIVATE,1,IPC_CREAT|00666);/该信号量用于消费者获 full3=semget(IPC_PRIVATE,1,IPC_CREAT|00666);/该信号量用于消费者获 empty1=semget(IPC_PRIVATE,1,IPC_CREAT|00666);/该信号量用于生产者获空闲缓冲区 empty2=semget(IPC_PRIVATE,1,IPC_CREAT|00666);/该信号量用于生产者获 empty3=semget(IPC_PRIVATE,1,IPC_CREAT|00666);/该信号量用于生产者获 mutxid=semget(IPC_PRIVATE,1,IPC_CREAT|00666);/该信号量用于对缓冲区的互斥/为信号灯赋初值 arg.val=1;if(semctl(full1,0,SETVAL,arg)=-1)perror(semctl setval error);arg.val=1;if(semctl(full2,0,SETVAL,arg)=-1)perror(semctl setval error);arg.val=1;if(semctl(full3,0,SETVAL,arg)=-1)perror(semctl setval error);arg.val=1;if(semctl(empty1,0,SETVAL,arg)=-1)perror(semctl setval error);arg.val=1;if(semctl(empty2,0,SETVAL,arg)=-1)perror(semctl setval error);arg.val=1;if(semctl(empty3,0,SETVAL,arg)=-1)perror(semctl setval error);arg.val=1;if(semctl(mutxid,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;/生产者进程if(fork()=0)名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 5 页 -int i=0;while(i 5)semop(empty1,&P,1);/申请空闲缓冲区 semop(empty2,&P,1);semop(empty3,&P,1);semop(mutxid,&P,1);/申请对缓冲区的互斥操作array*(set)%MAXSEM=i+1;/放入数据到缓冲区 printf(Producer%dn,array(*set)%MAXSEM);(*set)+;semop(mutxid,&V,1);/释放信号量 semop(full1,&V,1);semop(full2,&V,1);semop(full3,&V,1);i+;sleep(2);printf(Producer is overn);exit(0);else/ConsumerA 进程if(fork()=0)while(1)semop(full1,&P,1);/申请数据 semop(mutxid,&P,1);/申请对缓冲区的互斥操作 printf(The ComsumerA Get Number%dn,array(*get)%MAXSEM);(*get)+;semop(mutxid,&V,1);/释放信号量 semop(empty1,&V,1);sleep(1);printf(ConsumerA is over);exit(0);else /Consumer B 进程if(fork()=0)while(1)semop(full2,&P,1);semop(mutxid,&P,1);printf(The ComsumerB Get Number%dn,array(*get)%MAXSEM);(*get)+;semop(mutxid,&V,1);名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 5 页 -semop(empty2,&V,1);sleep(1);printf(ConsumerB is overn);exit(0);else /Consumer c 进程if(fork()=0)while(1)semop(full3,&P,1);semop(mutxid,&P,1);printf(The Comsumerc Get Number%dn,array(*get)%MAXSEM);(*get)+;semop(mutxid,&V,1);semop(empty3,&V,1);sleep(1);printf(Consumerc is overn);exit(0);return 0;【运行结果】名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 5 页 -【实验总结】通过此次 Linux 进程同步与通信实验,我懂得了如何创建虚拟主存,如何使用虚拟主存;结合本次实验,我对信号量创建,初始化,使用信号量等更深入了解,实践比当当看课本更有效;还有在做实验前要先弄懂实验的原理,并能够简单的画出该实验的流程图,和主流程图,这样在后面编写代码就更加容易,不会出现混乱现象!还有对信号量赋初值时一定要正确,在哪里用P,V,操作要正确,不能乱来用;在本次实验中还用到了内存映射等内容。名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 5 页 -
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号