![试验四进程通信_第1页](http://file4.renrendoc.com/view/3dba0159b5de19e1afe5fffe5c6c2a1e/3dba0159b5de19e1afe5fffe5c6c2a1e1.gif)
![试验四进程通信_第2页](http://file4.renrendoc.com/view/3dba0159b5de19e1afe5fffe5c6c2a1e/3dba0159b5de19e1afe5fffe5c6c2a1e2.gif)
![试验四进程通信_第3页](http://file4.renrendoc.com/view/3dba0159b5de19e1afe5fffe5c6c2a1e/3dba0159b5de19e1afe5fffe5c6c2a1e3.gif)
![试验四进程通信_第4页](http://file4.renrendoc.com/view/3dba0159b5de19e1afe5fffe5c6c2a1e/3dba0159b5de19e1afe5fffe5c6c2a1e4.gif)
![试验四进程通信_第5页](http://file4.renrendoc.com/view/3dba0159b5de19e1afe5fffe5c6c2a1e/3dba0159b5de19e1afe5fffe5c6c2a1e5.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、实验四 进程间通信一、实验目的.掌握利用管道机制实现进程间的通信的方法.掌握利用消息缓冲队列机制实现进程间的通信的方法.掌握利用共享存储区机制实现进程间的通信的方法. 了解Linux系统中进程软中断通信的基本原理二、实验学时2学时三、实验内容1.掌握实现进程间通信的系统调用的功能和方法进程通信,是指进程之间交换信息。 从这个意义上讲,进程之间的同步、互斥也是一种 信息交换,也是一种通信。但是,这里所说的 通信”是指进程之间交换较多的信息这样一种 情况,特别是在由数据相关和有合作关系的进程之间,这种信息交换是十分必要和数量较大的。进程间通信是协调解决多个进程之间的约束关系,实现进程共同进展的关键
2、技术,是多道系统中控制进程并发执行必不可少的机制。(1)进程的通信方式:a.直接通信是指信息直接传递给接收方,如管道。在发送时,指定接收方的地址或标识,也可以指定多个接收方或广播式地址,send(Receiver, message%在接收时,允许接收来自任意发送方的消息,并在读出消息的同时获取发送方的地址,receive(Sender,message)ob.间接通信:借助于收发双方进程之外的共享数据结构作为通信中转,如消息队列。这种 数据结构称为缓冲区或信箱。通常收方和发方的数目可以是任意的。(2)进程间通信的类型:a.共享存储器系统: 基于共享数据结构的通信方式 :只能传递状态和整数值(控制
3、信息),包括进程互斥和同步所采用的信号量机制。速度快,但传送信息量小,编程复杂,属于低级通信;基于共享存储区的通信方式 :能够传送任意数量的数据,属于高级通信。b.消息传递系统:在消息传递系统中,进程间的数据交换以消息为单位,用户直接利用系 统提供的一组通信命令(原语)来实现通信。c.管道通信:管道是一条在进程间以字节流方式传送的通信通道。它由OS核心的缓冲区(通常几十KB)来实现,是单向的;在实质上,是一个有 OS维护的特殊共享文件,常用于命 令行所指定的输入输出重定向和管道命令。在使用管道前要建立相应的管道,然后才可使用。Linux 管道a.无名管道:一个可以在文件系统中长期存在的、具有路
4、径名的文件。 用系统调用mknod()建立。它克服无名管道使用上的局限性,可让更多的进程也能利用管道进行通信。因而其它进程可以知道它的存在,并能利用路径名来访问该文件。对有名管道的访问方式与访问其他 文件一样,需先用open()打开。通过pipe系统调用可以创建无名管道,得到两个文件描述 符,分别用于写和读。int pipe(int fd2); /头文件 unistd.h,返回值:0 (成功),-1 (发生错误)文件描述符fd0为读端,fd1为写端通过系统调用write和read进行管道的写和读read(fd,buf,nbyte)从fd所指示的文件中读出 nbyte个字节的数据,并将它们送至由
5、指针 buf所指 示的缓冲区中。如该文件被加锁,等待,直到锁打开为止。write(fd,buf,nbyte)把nbyte个字节的数据,从buf所指向的缓冲区写到由fd所指向的文件中。如文件加锁,暂停写入,直至开锁。参数定义:int read(fd,buf,nbyte); /* write(fd,buf,nbyte)参数定义同 read*/int fd;char *buf;unsigned nbyte;进程间双向通信,通常需要两个管道只适用于父子进程之间或父进程安排的各个子进程之间b. Linux中的有名管道,可通过 mknod系统调用建立:指定 mode为S_IFIFO,或调用C库 函数mkf
6、ifo产生-int mknod(const char *path, mode_t mode, dev_t dev)-int mkfifo(const chat *path, mode_t mode)(4)消息缓冲机制消息(message)与窗口系统中的消息”不同。通常是不定长数据块。消息的发送不需要接收方准备好,随时可发送。相应的数据结构:type message buffer = recordsendersizetextnextendLinux消息:消息队列(message queue):每个message不定长,由类型(type)和正文(text)组成Linux 消息队列 API:头文件
7、sys/types.h, sys/ipc.h, sys/msg.hmsgget依据用户给出的整数值 key,创建新消息队列或打开现有消息队列,返回一个 消息队列ID;msgsnd发送消息;msgrcv接收消息,可以指定消息类型;没有消息时,返回 -1;msgctl对消息队列进行控制,如删除消息队列;通过指定多种消息类型,可以在一个消息队列中建立多个虚拟信道注意:消息队列不随创建它的进程的终止而自动撤销,必须用msgctl(msgqid, IPC_RMID,0)。另外,msgget获得消息队列ID之后,fork创建子进程,在子进程中能继承该消息队列 ID而不必再一次msggetint msgge
8、t(key_t key, int flag1语法格式:msgqid=msgget(key, flag)功能:获得一个消息的描述符,该描述符指定一个消息对流以便于其他系统调用。其中,key由系统规定类型,sys/type.ho flag本身由操作允许权和控制命令值相或“得到,如:IPC_CREAT|0400表示是否该队列应被创建,IPC_EXCL|0400表示该队列的创建应是互斥的。msgqid是该系统调用返回的描述符,失败则返回一1。int msgsnd(int id, struct msgbuf *msgp, int size, int flag);功能:发送一消息。其中,id为返回消息队列
9、的描述符。msgp指向用户存储区的一个构造体指针。size指示由msgp指向的数据结构中字符数组的长度,即消息长度,该数组的 最大值由MSGMAX 字体可调用参数来确定。flag规定当核心用尽内部缓冲空间时应执行 的动作:若在flag中未设置IPC_NOWAIT ,则当该消息队列中的字节数超过一最大值时,或 系统范围的消息数超过某一最大值时,调用msgsnd进程阻塞;若设置IPC_NOWAIT ,则在此情况下,msgsnd直接返回。int msgrcv(int id, struct msgbuf *msgp, int size, int type, int flag);语法格式: count=
10、msgrcv(id, msgp, size, type, flag)功能:接收一消息,count返回消息正文的字节数。 其中,struct msgbuflong mtyoe; char mtext ;id 消息队列的描述符。msgp用来存放欲接收消息的用户数据结构的地址。size指示msgp中数据数组的大小。type的第一个消息;为负,接IPC_NOWAIT ,则立即返回;size,核心截断所接收的消息。type为0接收该队列的第一个消息;为正,接收类型为 收小于或等于type绝对值的最低类型的第一个消息。flag规定倘若该队列无消息,核心应当做什么事。若设置 若在flag中设置MSG_NOE
11、RROR ,且所接收的消息大学大于int msgctl(int id, int cmd, struct msgid_ds *buf);功能:查询一个消息描述符的状态,设置它的状态及删除一个消息描述符。其中,id用来识别该消息的描述符。cmd规定命令的类型:IPC_STAT将与id相关联的消息队列首标读入 buf; IPC_SET为IPC RMID 删除 id这个消息队列设置有效的用户和小组表示及操作允许权和字节的数量; 的消息队列。buf是含有控制参数或查询结果的用户数据结构的地址。struct ipc_permushort uid;/当前用户 id ushort uid;/当前进程组id u
12、short cuid; 创建用户 id ushort cgid; 创建进程组id ushort mode; /存取许可权 short pad1; long pad2; 由系统使用 struct msgid_dsstruct ipc_perm msgperm; /许可权结构 short pad17; /由系统使用ushort onsg_qnum; 队歹 U 上 7 肖息ushort msg_qbytes; /队列上最大字节数 ushort msg_lspid;/最后发送消息的PID ushort msg_lrpid; /最后接收消息的 PID time_t msg_stime; /最后发送消息的
13、时间 time_t msg_rtime; /最后接收消息的时间 time_t msg_ctime; 最后更改消息的时间(5)共享存储区(shared memory)相当于内存,可以任意读写和使用任意数据结构(当然,对指针要注意),需要进程互 斥和同步的辅助来确保数据一致性。Linux的共享存储区:-创建或打开共享存储区(shmget):依据用户给出的整数值 key,创建新区或打开现有区, 返回一个共享存储区ID。-连接共享存储区(shmat):连接共享存储区到本进程的地址空间,可以指定虚拟地址fork创建的子进或由系统分配,返回共享存储区首地址。父进程已连接的共享存储区可被 程继承。-拆除共享
14、存储区连接(shmdt):拆除共享存储区与本进程地址空间的连接。-共享存储区控制(shmctl):对共享存储区进行控制。如:共享存储区的删除需要显式调用 shmctl(shmid, IPC_RMID, 0);一头文件: sys/types.h, /sys/ipc.h, sys/shm.h int shmget(key_t key, int size, int flag);语法格式: shmid=shmget(key, size, flag)功能:创建一个关键字为 key,长度为size的共享存储区。其中,size为存储区的字节 数。key、flag与系统调用msgget相同。int shmat
15、(int id, char *addr, int flag);语法格式: virtaddr=shmat(id, addr, flag)功能:从逻辑上将一个共享存储区附接到进程的虚拟地址空间上。id为共享存储区的标识符。addr用户要使用共享存储区附接的虚地址,若为 0,系统选择一个适当的地址来附接该共享区。flag规定对此区的读写权限,以及系统是否应对用户规定的地址做舍入操作:如果 flag 中设置了 shm_rnd即表示操作系统在必要时舍去这个地址;如果设置了shm_rdonly,表示只允许读操作。viraddr是附接的虚地址。int shmdt(char *addr);功能:把一个共享存储
16、区从指定进程的虚地址空间断开,当调用成功,返回0值;不成功,返回-1。addr为系统调用shmat所返回的地址。int shmctl(int id, int cmd, struct shmid_ds *buf);功能:对与共享存储区关联的各种参数进行操作,从而对共享存储区进行控制。调用成功返回0,否则-1。其中,id为被共享存储区的描述符。cmd规定命令的类型:IPC_STAT返回包含在指定的shmid相关数据结构中的状态信 息,并且把它放置在用户存储区中的*buf指针所指的数据结构中。执行此命令的进程必须有读取允许权;IPC_SET对于指定的shmid,为它设置有效用户和小组标识和操作存取权
17、; IPC_RMID删除指定的shmid以及与它相关的共享存储区的数据结构;SHM_LOCK 在内存中锁定指定的共享存储区,必须是超级用户才可以进行此项操作。buf是一个用户级数据结构地址。2.编写程序实现进程的管道通信。参考程序4.1#include #include #include #includeint pid1,pid2;main() int fd2;char outpipe100,inpipe100;pipe(fd); /*创建一个管道*/while (pid1=fork( )=-1);if(pid1=0)lockf(fd1,1,0);sprintf(outpipe,child 1
18、 process issending message!);/* 把串放入数组 outpipe 中*/write(fd1,outpipe,50);sleep(5);lockf(fd1,0,0);exit(0);elsewhile(pid2=fork( )=-1);if(pid2=0) lockf(fd1,1,0);sprintf(outpipe,child 2 process is sending message!);write(fd1,outpipe,50);sleep(5);lockf(fd1,0,0);exit(0);)elsewait(0);read(fd0,inpipe,50); /*
19、 从管道中读长为50字节白串*/阅读并运行程序并回答以下问题:printf(%sn,inpipe);wait(0);read(fd0,inpipe,50); printf(%sn,inpipe);exit(0);)问题1:该程序中使用的管道是有名管道还是无名管道?程序中红色部分的含义是什么?问题2:程序的含义是什么?运行结果是什么?为什么?.编写两个程序client.c 和server.c ,分别用于消息的发送和接收参考程序4.2server.c参考程序如下:#include #include #include #include #include #define MSGKEY 75 struc
20、t msgform long mtype;char mtext1000;msg;int msgqid; void server() msgqid=msgget(MSGKEY,0777|IPC_CREAT);/*创建75#消息队列*/ do msgrcv(msgqid,&msg,1030,0,0);/*接收消息*/printf(server)receivedn);while(msg.mtype!=1);msgctl(msgqid,IPC_RMID,0);/*删除消息队列,归还资源 */exit(0); main() server();client.c参考程序如下:#include #includ
21、e #include #include #include #define MSGKEY 75 struct msgform long mtype;char mtext1000;msg;int msgqid; void client() int i;msgqid=msgget(MSGKEY,0777);/*打开75#W息队列*/ for(i=10;i=1;i-) msg.mtype=i;printf(client)sentn);msgsnd(msgqid,&msg,1024,0);/*发送消息*/ exit(0);main()client();()建议该题目的运行方法为:将上述两个程序分别编译为
22、server和client,并按以下方式执行:./server & /*当在前台运行某个作业时,终端被该作业占据;而在后台运行作业时,它不会占据终端。可以使用 &命令把作业放到后台执行。该命令的一般形式为:命令 &*/ipcs -q/*输出有关信息队列(message queue)勺信息*/./client阅读并运行程序并回答以下问题:问题1:运行结果是什么?该程序为什么需要在后台运行server.c?若不如此会出现什么现象?为什么?问题2:两个程序的含义是什么?请解释其运行结果的含义?.使用共享存储区来实现两个进程之间的通信。参考程序4.3#include #include#include
23、#include #include #define SHMKEY 75 int shmid,i,p1,p2;int *addr;void CLIENT()/* 发送过程 */ (int i;shmid=shmget(SHMKEY,1024,0777);/* 打 开共享存储区*/addr= (int *)shmat(shmid,0,0); /*获取共享 存储区的首地址*/for (i=29;i=0;i-)( while (*addr!=-1);/* 判断是否可写 */ *addr=i;/* 写数据 */ printf(%d,*addr);printf(client)sentn);) exit(0
24、);)void SERVER()/* 接收进程 */阅读并运行程序并回答以下问题:问题1:运行结果是什么? 问题2:(int i;shmid=shmget(SHMKEY,1024,0777|IPC_CREAT); /*创建共享存储区*/addr= (int *)shmat(shmid,0,0);do(*addr=-1;while (*addr=-1);/*判断信息是否传来 */ printf(%d,*addr+30); /* 读,并加工数据*/printf(server)receivedn);while(*addr);shmctl(shmid,IPC_RMID,0); /* 撤消共享存储区,归
25、还资源*/exit(0);main()(while (p1=fork()=-1);/* 父进程*/if (p1=0) SERVER();/* 子进程 p1*/while (p2=fork()=-1); /* 父进程 */if (p2=0) CLIENT。;/* 子进程 p2*/wait(0); /* 父进程 */wait(0); /* 父进程 */两个程序的含义是什么?请解释其运行结果的含义?5*,编制一段程序,使其实现进程的软中断通信。要求:使用系统调用fork ()创建两个子进程,再用系统调用signal ()让父进程捕捉键盘上来的中断信号(即按Del键);当捕捉到中断信号后,父进程用系统
26、调用kill ()向两个子进程发出信号,子进程捕捉到信号后分别输出 下列信息后终止:Child process 1 is killed by parent!Child process 2 is killed by parent!父进程等待两个子进程终止后,输出如下的信息后终止: Parent process is killed! 参考资料 1 .信号的基本概念每个信号都对应一个正整数常量(称为signal number,即信号编号。定义在系统头文件signal.h中),代表同一用户的诸进程之间传送事先约定的信息的类型,用于通知某 进程发生了某异常事件。每个进程在运行时,都要通过信号机制来检查是
27、否有信号到达。若有,便中断正在执行的程序,转向与该信号相对应的处理程序,以完成对该事件的处理; 处理结束后再返回到原来的断点继续执行。实质上,信号机制是对中断机制的一种模拟,故在早期的UNIX版本中又把它称为软中断。信号与中断的相似点:(1)采用了相同的异步通信方式;(2 )当检测出有信号或中断请求时,都暂停正在执行的程序而转去执行相应的处理程序;(3)都在处理完毕后返回到原来的断点;(4)对信号或中断都可进行屏蔽。信号与中断的区别:(1 )中断有优先级,而信号没有优先级,所有的信号都是平等的;(2 )信号处理程序是在用户态下运行的,而中断处理程序是在核心态下运行;(3)中断响应是及时的,而信
28、号响应通常都有较大的时间延迟。信号机制具有以下三方面的功能:(1 )发送信号。发送信号的程序用系统调用kill()实现;(2 )预置对信号的处理方式。接收信号的程序用signal()来实现对处理方式的预置;(3 )收受信号的进程按事先的规定完成对相应事件的处理。.信号的发送信号的发送,是指由发送进程把信号送到指定进程的信号域的某一位上。如果目标进程正在一个可被中断的优先级上睡眠, 核心便将它唤醒, 发送进程就此结束。 一个进程可能在 其信号域中有多个位被置位,代表有多种类型的信号到达,但对于一类信号,进程却只能记 住其中的某一个。进程用kill()向一个进程或一组进程发送一个信号。.对信号的处
29、理当一个进程要进入或退出一个低优先级睡眠状态时,或一个进程即将从核心态返回用户态时,核心都要检查该进程是否已收到软中断。当进程处于核心态时,即使收到软中断也不予理睬;只有当它返回到用户态后,才处理软中断信号。 对软中断信号的处理分三种情况进行:(1 )如果进程收到的软中断是一个已决定要忽略的信号( function=1 ),进程不做任何处 理便立即返回;(2 )进程收到软中断后便退出( function=0 );(3 )执行用户设置的软中断处理程序。.所涉及的中断调用1) kill()系统调用格式int kill(pid,sig)参数定义int pid,sig;其中,pid是一个或一组进程的标
30、识符,参数 sig是要发送的软中断信号。(1 ) pid0时,核心将信号发送给进程pid。(2 ) pid=0时,核心将信号发送给与发送进程同组的所有进程。(3 ) pid=-1时,核心将信号发送给所有用户标识符真正等于发送进程的有效用户标识号 的进程。2 ) signal()预置对信号的处理方式,允许调用进程控制软中断信号。系统调用格式signal(sig,function)头文件为#include 参数定义signal(sig,function)int sig;void (*func)()其中sig用于指定信号的类型,sig为0则表示没有收到任何信号,余者如下表:值名字说明01SIGHUP
31、挂起(hangup )02SIGINT中断,当用户从键盘按 Ac键或Abreak键时03SIGQUIT退出,当用户从键盘按quit键时041SIGILL法指令_05SIGTRAP跟踪陷阱(trace trap),启动进程,跟踪代码的执行06SIGIOTOT指令07SIGEMTEMT指令08SIGFPE浮点运算溢出09SIGKILL杀死、终止进程10SIGBUS总线错误11SIGSEGV段违例(segmentation violation ),进程试图去访问其虚地址空间以外的位置12SIGSYS系统调用中参数错,如系统调用号非法13SIGPIPE句某个非读管道中写入数据14SIGALRM闹钟。当
32、某进程希望在某时间后接收信号时发此信号15SIGTERM软件终止(software termination )16SIGUSR1用户自定义信号117SIGUSR2用户自定义信号218 SIGCLD某个子进程死19 SIGPWR电源故障function :在该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为 参数调用该函数,对除了信号SIGKILL , SIGTRAP和SIGPWR以外的信号,核心自动地重新设置软中断信号处理程序的值为SIG_DFL , 一个进程不能捕获 SIGKILL信号。function的解释如下:(1 ) function=1时,进程对sig类信号不予理睬,亦即屏蔽了该类信号;(2 ) function=0时,缺省值,进程在收到sig信号后应终止自己;(3 ) function为非0 ,非1类整数时,function的值即作为信号处理程序的指针。参考程序4.4#include #include#include #include void waiting( ),stop(); int wait_mark;main()int p1,p2,stdout;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年五年级品社下册《校园红绿灯》说课稿 上海科教版
- 2025股份转让合同
- 煤矿集中检修方案
- 襄阳防腐木屋施工方案
- 青岛垂直植物墙施工方案
- 2024-2025学年高中历史 专题八 当今世界经济的全球化趋势 第三课 经济全球化的世界说课稿 人民版必修2
- 净化设备合同范例
- 28 枣核 说课稿-2023-2024学年统编版语文三年级下册
- Unit 3 Fit for life Welcome to the unit 说课稿-2024-2025学年高中英语译林版(2020)选择性必修第二册
- 桥面防腐木施工方案
- 线性系统理论郑大钟第二版
- 宁骚公共政策学完整版笔记
- 走进奥运奥运知识简介
- 项目负责人考试题库含答案
- GB/T 7251.5-2017低压成套开关设备和控制设备第5部分:公用电网电力配电成套设备
- 2023年湖南高速铁路职业技术学院高职单招(数学)试题库含答案解析
- 中考语文非连续性文本阅读10篇专项练习及答案
- 勇者斗恶龙9(DQ9)全任务攻略
- 经颅磁刺激的基础知识及临床应用参考教学课件
- 小学语文人教四年级上册第四单元群文阅读“神话故事之人物形象”PPT
- ISO 31000-2018 风险管理标准-中文版
评论
0/150
提交评论