进程实验--进程间通信(管道、消息、共享内存、软中断).docx
进程实验31.inux进程间通信一、软中断信号的处理,实现同一用户的各进程之间的通信。相关的系统调用 kill(pid,sig):发送信号 signal(sig,func):指定进程对信号Sig的处理行为是调用函数func。程序清单#include<unistd.h>#include<stdio.h>#include<signal.h>voidwaiting();voidstop();intwait_mark;main()(intp1.p2;while(pl=fbrk()=-l);if(pl>O)(while(p2=fbrk()=-1);if(p2>0)printf(,parentn");*父进程在此完成某个操作、或接收到用户从键盘输入的特殊按键命令后发出下面的信号。这里省略。*/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(,childprocess1iskelledbyparent!n,');exit(0);1)voidwaiting()(While(Wai1.mark!=0);voidstop()waijmark=O;输入并运行此程序,分析程序的运行结果。二、消息的创立、发送和接收 多个进程通过访问一个公共的消息队列来交换信息 消息队列:即消息的一个链表 任何进程都可以向消息队列中发送消息(消息类型及正文),其它进程都可以从消息队列中根据类型获取相应的消息 相关的系统调用头文件:#include<sysmsg.h>翻开或创立消息队列:intmsgget(key_tkey,intmsgflg);key:消息队列的键 1PC_PRIVATE:创立一个私有的消息队列 其它:可被多个进程使用的消息队列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那么不等待消息发出就返回返回值:成功返回0,错误返回-I(置errno)接收消息intmsgrcv(intmsgid,void*msgp,size_tmtexsize,longmsgtype,intflags);参数:与msgsnd类似msgtype >0:只接收指定类型消息的第一个 =0:不管什么消息类型都读取队列中第一个数据 <0:接收等于或小于其绝对值的最低类型的第一个,如有5、6、17三类,假设为-6,那么获取类型5的。返回值 成功:返回消息正文字节数 错误:返回-1(置errno)程序清单#include<stdio.h>#include<systypes.h>#include<sysmsg.h>#include<sysipc.h>#defineMSGKEY75structmsgfbrm(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,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();wait(0);wait(0);)编辑并运行程序,并分析程序的运行结果。思考题:符号常量MSGKEY有什么作用server和Client不使用同一个MSGKEY会出现什么问题程序扩展:Client和SerVer之间若何通过软中断信号控制进程的推进速度,使得Client每发送一个消息,server就接收一个消息,然后Client再发送下一个消息三、共享存储区的创立、发送和接收同一系统中的几个进程可共享某块物理内存。include<sysshm.h>翻开或创立创立共享区:intshmget(kev_tkey,size_tsize,intshmflg);参数 key:键值 IPC_PRIVATE:创立一个私有的Shm 其它:非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),默认是读写。返回值成功:进程中该内存段的地址错误:-1程序清单:#include<stdio.h>#include<systypes.h>#include<sysmsg.h>#inciude<sysipc.h>#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);addr=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个整数、并输出。