《进程实验--进程间通信(管道、消息、共享内存、软中断).docx》由会员分享,可在线阅读,更多相关《进程实验--进程间通信(管道、消息、共享内存、软中断).docx(5页珍藏版)》请在课桌文档上搜索。
1、进程实验31.inux进程间通信一、软中断信号的处理,实现同一用户的各进程之间的通信。相关的系统调用 kill(pid,sig):发送信号 signal(sig,func):指定进程对信号Sig的处理行为是调用函数func。程序清单#include#include#includevoidwaiting();voidstop();intwait_mark;main()(intp1.p2;while(pl=fbrk()=-l);if(plO)(while(p2=fbrk()=-1);if(p20)printf(,parentn);*父进程在此完成某个操作、或接收到用户从键盘输入的特殊按键命令后发出
2、下面的信号。这里省略。*/kill(pl,16);kill(p2,17);wait(0);wait(0);printf(parentprocessidkilled!n);exit(O);)else/*p2=0*/(printf(,p2n);WaiJmark=1;signal(!7,stop);waiting();printf(,childprocess2iskilledbyparent!n);exit(O);else*pl=0*/printf(,pln);Wai1.mark=I;signal(16,stop);waiting();printf(,childprocess1iskelledbyp
3、arent!n,);exit(0);1)voidwaiting()(While(Wai1.mark!=0);voidstop()waijmark=O;输入并运行此程序,分析程序的运行结果。二、消息的创立、发送和接收 多个进程通过访问一个公共的消息队列来交换信息 消息队列:即消息的一个链表 任何进程都可以向消息队列中发送消息(消息类型及正文),其它进程都可以从消息队列中根据类型获取相应的消息 相关的系统调用头文件:#include翻开或创立消息队列:intmsgget(key_tkey,intmsgflg);key:消息队列的键 1PC_PRIVATE:创立一个私有的消息队列 其它:可被多个进程
4、使用的消息队列msgflg:设置操作类型及访问权限IPC-CREAt/IPC-EXC1.获得或设置消息队列属性:intmsgctl(intmsgid,intcmd,structmsqid_ds*data);发送消息:intmsgsnd(intmsgid,constvoid*msgp,size_tmsgsize,intflags);参数 msgid:消息队列标识符id msgp:指针,用户自定义缓冲区,可定义成构造体类型,包含两项longmlype;代表消息类型charmtextMTEXTSIZE;消息正文 msgsize:要发送消息正文的长度 mfiags:标志,假设设置Ipclnowait那
5、么不等待消息发出就返回返回值:成功返回0,错误返回-I(置errno)接收消息intmsgrcv(intmsgid,void*msgp,size_tmtexsize,longmsgtype,intflags);参数:与msgsnd类似msgtype 0:只接收指定类型消息的第一个 =0:不管什么消息类型都读取队列中第一个数据 0:接收等于或小于其绝对值的最低类型的第一个,如有5、6、17三类,假设为-6,那么获取类型5的。返回值 成功:返回消息正文字节数 错误:返回-1(置errno)程序清单#include#include#include#include#defineMSGKEY75stru
6、ctmsgfbrm(longmtype;charmsgtext1030;msg;intmsgqid,i;voidC1.IENT()(inti;charstring-i5;msgqid=msgget(MSGKEY,0777);for(i=10;i=l;i-)(msg.mtype=i;printf(,(client)sentn11);sprintf(msg.msgtext,thecontentofmessage);sprintf(string_i,%dn,i);strcat(msg.msgtext,string_i);strcat(msg.msgtext,n);msgsnd(msgqid,&msg
7、,1030,0);)exit(0);)voidSERVER()(msgqid=msgget(MSGKEY,0777|IPC_CREAT);dofmsgrcv(msgqid,&msg,1030,0,0);printf(,(server)receivedmessage%dn,msg.mtype);Printff%sn”,msg.msgtext);while(msg.mtype!=l);msgctl(msgqid,IPC_RMID,0);exit(0);)main()(while(i=fork()=-1);if(!i)SERVER();while(i=fork()=-l);if(!i)C1.1ENT
8、();wait(0);wait(0);)编辑并运行程序,并分析程序的运行结果。思考题:符号常量MSGKEY有什么作用server和Client不使用同一个MSGKEY会出现什么问题程序扩展:Client和SerVer之间若何通过软中断信号控制进程的推进速度,使得Client每发送一个消息,server就接收一个消息,然后Client再发送下一个消息三、共享存储区的创立、发送和接收同一系统中的几个进程可共享某块物理内存。include翻开或创立创立共享区:intshmget(kev_tkey,size_tsize,intshmflg);参数 key:键值 IPC_PRIVATE:创立一个私有的S
9、hm 其它:非IPC.PRIVATE整数值。 size:指明shm的大小,假设shm已经存在,那么size应为0 shmflg:设置访问权限及IPC_CREAT/IPC_EXC1. 返回值成功:该Shm的id,当前进程是其拥有者及创立者错误:-1将共享内存连接到进程中:void*shmat(intShmid,constvoid*shmaddr,intflags);参数 shmid:共享内存标识符id shmaddr:进程映射内存段的地址,可指定,但一般设为NU1.1.表示由系统安排。 flags:对该内存的段设置是否只读(SHM_RDON1.Y),默认是读写。返回值成功:进程中该内存段的地址错
10、误:-1程序清单:#include#include#include#inciude#defineSHMKEY75intshmid,i;int*addr;voidC1.IENT()inti;shmid=shmget(SHMKEY,1024,0777);addr=shmat(shmid,0,0);for(i=5;i=0;i-)(while(*addr!=-l);printf(client)sent,);*addr=i;printf(11clienti:%dn11,i);)exit(O);1voidSERVER()(shmid=shmget(SHMKEY,1024,0777IPC-CREAT);ad
11、dr=shmat(shmid,O,O);do(*addr=-1;while(*addr=-l);printf(server)received,11);printf(server*addr%dn11,*addr);while(*addr);shmctl(shmid,IPC_RMID,O);exit(O);)main()(while(i=fork()=-1);if(!i)SERVER();while(i=fork()=-1);if(!i)C1.IENT();wait(0);wait(0);)编辑并运行程序,并分析程序的运行结果。在此根基上对程序进展修改:使得每次循环中:CuENT向共享区发送10个整数,SERVER从共享区接收10个整数、并输出。