实验六进程间通信

上传人:tia****nde 文档编号:66950959 上传时间:2019-01-06 格式:PPT 页数:26 大小:261KB
返回 下载 相关 举报
实验六进程间通信_第1页
第1页 / 共26页
实验六进程间通信_第2页
第2页 / 共26页
实验六进程间通信_第3页
第3页 / 共26页
实验六进程间通信_第4页
第4页 / 共26页
实验六进程间通信_第5页
第5页 / 共26页
点击查看更多>>
资源描述

《实验六进程间通信》由会员分享,可在线阅读,更多相关《实验六进程间通信(26页珍藏版)》请在金锄头文库上搜索。

1、实验六 进程间通信,实验六 进程间通信,预备知识 Linux进程间通信 进程软中断通信 管道和消息队列 实验指导 软中断通信函数 管道通信的使用 消息队列的应用 实验目的、内容,1.1 Linux进程间通信,实现数据传输、数据共享、事件通知、资源共享和进程控制等 Linux的进程间通信方式 管道(Pipe)和有名管道(Named Pipe) 信号(Signal) 消息(Message)队列 共享内存 信号量(Semaphore) 套接口(Socket),1.1 Linux进程间通信管道和有名管道,管道用于具有亲缘关系进程间的通信 管道是半双工的,数据只能单向流动(双方通信需建立两个管道) 管道

2、只能用于父子进程或兄弟进程之间 管道对于管道两端的进程而言就是一个文件,并单独构成一种文件系统,存在于内存中 写管道的内容添加在管道缓冲区的末尾,读管道则从缓冲区头部读出 有名管道在普通管道具备功能基础上,通过给管道命名的方法变成管道文件,允许无亲缘关系进程间通过访问管道文件进行通信,1.1 Linux进程间通信信号,在一个或多个进程之间传递异步信号 类似于Windows下的消息,用于通知接收进程有某种事件发生 当某个信号出现时,系统有三种处理方式: 忽略信号:大多数信号使用,但SIGKIL和SIGSTOP不能被忽略 捕捉信号:通知内核在某种信号发生时,调用一个用户函数 执行系统默认动作:异常

3、终止(abort)、退出(exit)、忽略(ignore)、停止(stop)或继续(continue),1.1 Linux进程间通信消息队列,也叫报文队列,是消息的链接表 有两种类型的消息队列:POSIX消息队列和系统V消息队列 运行于同一台机器上的进程间通信,与管道类似 消息内存可根据需要自行定义,可忽略信号承载信息量少、管道只能承载无格式字节流以及缓冲区大小受限等缺点 可以用流管道或套接口方式取代,1.1 Linux进程间通信共享内存,在系统内核分配一块缓冲区,多个进程都可以访问该缓冲区 效率高:进程可以直接读写内存,不需任何数据拷贝,避免了内核空间与用户空间的切换 同步和协议都不受程序员

4、控制,必须确保将句柄传递给子进程和线程,需与其它通信机制结合使用,来达到进程间的同步及互斥 多用于存储应用程序的配置信息,1.1 Linux进程间通信信号量,也称信号灯,用来协调不同进程间的数据对象 提供对进程间共享资源访问控制的手段,用来保护共享资源 还可用于进程间及同一进程不同线程间的进程同步 两种类型 二值信号灯:取值只能为0或1,类似于互斥锁 计算信号灯:取值可以为任意非负值(受内核本身约束),1.1 Linux进程间通信套接口,也称套接字,用于不同机器之间的进程间通信 通信域是用来说明套接口通信的协议,创建套接口时要指明它的通信域 常见的有:UNIX域套接口、网际通信域 系统的网络编

5、程接口,以文件的形式实现(属于sockfs特殊文件系统),1.2 进程软中断通信,即信号,提供一种简单的处理异步事件的方法 信号机制是对中断机制的一种模拟,又称为软中断 信号与中断的相似点 采用了相同的异步通信方式 当检测出有信号或中断请求时,暂停正在执行的程序而转去执行相应的处理程序 处理完毕后返回到原来的断点 对信号或中断可以进行屏蔽 信号与中断的区别 中断有优先级,而信号没有优先级,所有的信号都是平等的 信号处理程序在用户态下运行,而中断处理程序在核心态下运行 中断响应是及时的,而信号响应通常都有较大的时间延迟,1.2 进程软中断通信信号机制的功能,发送信号 发送进程把信号送到指定进程信

6、号域的某一位上,如目标进程正在一个可被中断的优先级上睡眠,核心便将其唤醒 预置对信号的处理方式 进程处于核心态时,即使受到软中断也不予理睬;只有当它返回到用户态后,才处理软中断信号 收受信号的进程按事先规定完成对相应事件的处理,1.3 管道和消息队列无名管道,int pipe(int fd2);一般的文件I/O函数都可用 读数据规则 若管道的写端不存在,读出字节数为0 写端存在时,若请求字节数大于PIPE_BUF,则返回管道中的现有数据;否则返回请求的字节数 写入规则 不保证写入的原子性,若有空闲区域,写进程就会试图写入管道,若读进程不读走数据,则写操作将一直阻塞 管道读端存在时,写入数据才有

7、意义;否则,写进程将收到内核传来的SIFPIP信号,应用程序处理该信号或忽略(默认终止应用程序),1.3 管道和消息队列命名管道(1),int mkfifo(const char * pathname, mode t_mode); 增加了打开操作: 若当前打开操作是为读而打开,若已有进程为写而打开,则打开成功;否则,阻塞直到有相应进程为写而打开(设置了阻塞标识),或成功返回(未设置阻塞标识) 若当前打开操作是为写而打开,若已有进程为读而打开,则打开成功;否则,阻塞直到有进程为读而打开(设置了阻塞标识),或返回ENXIO错误(未设置阻塞标识),1.3 管道和消息队列命名管道(2),约定: 如果进

8、程为了从FIFO中读取数据而阻塞打开FIFO,那么称该进程内的读操作为设置了阻塞标志的读操作 如果进程为了向FIFO中写入数据而阻塞打开FIFO,那么称该进程内的写操作为设置了阻塞标志的写操作 读数据规则 若有进程写打开FIFO,且当前FIFO中无数据,则对于设置了阻塞标志的读操作,将一直阻塞;对无阻塞标志的读操作则返回-1 读打开的阻塞标志只对本进程第一个读操作施加作用,如果有多个读操作序列,则在第一个读操作被唤醒并完成后,后续的读操作将不再阻塞 如果没有进程写打开,则设置了阻塞标志的读操作阻塞,1.3 管道和消息队列命名管道(3),对于设置了阻塞标志的写操作: 当要写入的数据量不大于PIP

9、E_BUF时,若管道空闲缓冲区不足以容纳要写入的字节数,则睡眠,直到缓冲区满足要求时,一次性写操作(原子性) 当要写入的数据量大于PIPE_BUF时,缓冲区一有空闲区域,写进程就会试图写入数据,在写完所有请求写的数据后返回(非原子性) 对于没有设置阻塞标志的写操作: 当要写入的数据量大于PIPE_BUF时,在写满所有FIFO空闲缓冲区后,写操作返回(非原子性) 当要写入的数据量不大于PIPE_BUF时,若当前FIFO空闲缓冲区能够容纳请求写入的字节数,写完后成功返回;若当前FIFO空闲缓冲区不能容纳请求写入的字节数,则返回EAGAIN错误(原子性),1.3 管道和消息队列消息队列,消息的链表,

10、有写权限的进程可以向队列中按照一定的规则添加新消息;有读权限的进程则可以从消息队列中读出信息 消息队列是一个临界资源,读写操作必须互斥执行 消息队列独立于发送和接收进程,减少了在打开和关闭有名管道之间同步的困难 消息队列的操作: 打开或创建操作 读写操作 获得或设置消息队列属性,实验六 进程间通信,预备知识 Linux进程间通信 进程软中断通信 管道和消息队列 实验指导 软中断通信函数 管道通信的使用 消息队列的应用 实验目的、内容,2.1 软中断通信函数(1),向一个进程或一组进程发送一个信号: int kill(pid, sig) pid0时,核心将信号发送给进程pid pid0时,核心将

11、信号发送给与发送进程同组的所有进程 pid=-1时,核心将信号发送给所有用户标识符真正等于发送进程的有效用户标识号的进程 预置信号接收后的处理方式:signal(sig, function) function=1时,屏蔽该类信号 function=0时,收到sig信号后终止自己 function为非0、非1类整数时,执行用户设置的软中断处理程序,2.1 软中断通信函数(2),pid_t wait(int * status) 暂时停止目前进程的执行,直到有信号来或子进程结束 pid_t waitpid(pid_t pid, int * status, int options) pid的取值 pi

12、d=-1时,等待任何一个子进程退出,相当于wait() pid=0时,等待进程组ID与目前进程相同的任何子进程 pid-1时,等待进程组ID为pid绝对值的任何子进程 options有两个常数参数,可使用或运算,不用时设为0 WNOHANG:即使没有任何子进程退出,它也会立即返回 WUNTRACED:子进程进入暂停执行状态并马上返回,但结束状态不予以理会,2.2 管道通信的使用无名管道的使用,将数据写入管道:write() 管道长度受到限制,管道满时写入操作将被阻塞,直到管道中的数据被读取 fcntl()可将管道设置为非阻塞模式 从管道读取数据:read() 当数据被读取后,数据将自动被管道清

13、除 不能由一个进程向多个进程同时传递同一个数据 fcntl()可将管道读模式设置为非阻塞模式 关闭管道:close() 关闭读端口时,在管道上进行写操作的进程将收到SIGPIPE信号 关闭写端口时,进行读操作的read()函数将返回0,2.2 管道通信的使用命名管道的创建与读写,创建命名管道: int mknod(const char *path, mode_t mod, dev_t dev); int mkfifo(const char *path, mode_t mode); 命名管道必须先调用open()将其打开 同时用读写方式(O_RDWR)打开时,一定不会导致阻塞 以只读方式(O_R

14、DONLY)打开时,调用open()函数的进程将会被阻塞直到有写方打开管道 以写方式(O_WRONLY)打开时,阻塞直到有读方打开管道,2.3 消息队列的应用,消息队列的创建:msgget(key_t key, int msgflg); 消息的发送:msgsnd(int msgqid, const void *msgp_ptr, size_t msg_sz, int msgflg); 消息的接收:msgrcv(int msgqid, void *msgp_ptr, size_t msg_sz, long int msgtype, int msgflg); 消息队列的控制和撤销:msgctl(i

15、nt msgqid, int cmd, struct msqid_ds *buf);,实验六 进程间通信,预备知识 Linux进程间通信 进程软中断通信 管道和消息队列 实验指导 软中断通信函数 管道通信的使用 消息队列的应用 实验目的、内容,3.1 实验目的,掌握Linux系统进程软中断通信的基本原理和实现方法 了解管道通信的特点,掌握管道通信的使用方法 了解消息队列通信机制及原理,掌握消息队列相关系统调用的使用方法及功能,3.2 实验内容(1),进程的信号通信 编写程序。用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘的中断信号(即按Del键);捕捉到中断信号后,

16、父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: Child process 1 is killed by parent. Child process 2 is killed by parent. 父进程等待两个子进程终止后,输出如下信息后终止: Parent process is killed. 然后在程序中,增加语句signal(SIGINT, SIG_IGN)和语句signal(SIGQUIT, SIG_IGN),观察执行结果是否有变化,并分析原因。,3.2 实验内容(2),进程的管道通信 编写程序,实现进程的管道通信:父进程使用系统调用pipe()建立一个管道。创建两个子进程p1和p2,分别向管道个发一条信息后结束: Child 1 is sending a message to parent. Child 2 is sending a message to parent. 父进程从管道中分别接收两个子进程发来的消息并显示在屏幕上,然后父进程结束。要求父进程先接受子进程p1发来的消息,然后再接收子进程p

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号