操作系统进程间通信.pptx

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多

进程间通信

概述

实现进程间通信(IPC)的方法很多,但从历史来看,很多都不可移植,经过多年的发展,已经有很大的统一

IPC的方法主要包括:

管道

消息队列

信号量

共享内存

套接字

管道

管道是最古道的IPC方式,在历史上,有两方面的限制:

只能以半双工方式工作

管道的两端必须是具有公共祖先的进程

但最近的Unix系统大多都取消这两方面的限制,但为了兼容性原因,很多应用我们仍然假设管道只能以半双工方式工作

无名管道和命名管道

管道可以分为无名管道和命名管道两类

无名管道没有名字,只能工作在具有同一个祖先进程的若干个进程中

命名管道,又叫FIFO管道,可以在任何两个进程之间工作

无名管道

通过调用pipe系统调用可以创建一个无名管道

intpipe(intfiledes[2]);

由参数filedes返回两个文件描述符:filedes[0]为读而打开,filedes[1]为写而打开,filedes[1]的输出是filedes[0]的输入

管道

内核

用户进程

fd[0]

fd[1]

使用管道

单个进程中管道基本没有什么用处

调用pipe创建管道后,再调用fork,就创建了从父进程到子进程(或反向)的IPC通道

还可以通过多次调用fork在两个子进程之间连接IPC通道

管道的一方进程应该关闭自己不需要的管道描述符

管道

内核

父进程

fd[0]

fd[1]

子进程

fd[0]

fd[1]

从子进程到父进程的管道

管道

内核

父进程

fd[0]

子进程

fd[1]

两条规则

当管道的一端被关闭后,下列两条规则起作用

当读一个写端被关闭的管道时,所有数据被读取后,read返回0。(只要管道的写端还有进程,就不会产生文件结束)

如果写一个读端被关闭的管道,则产生信号SIGPIPE,如果忽略或捕获该信号并返回,则write返回-1,errno设置为EPIPE

一段典型的代码

intmain()

{

intfd[2];

pipe(fd);

if((pid_tpid=fork())0)

{

close(fd[0]);

write(fd[1],....);

......

}

else

{

close(fd[1]);

read(fd[0],....);

}

}

FIFO管道(命名管道)

无名管道只能工作在具有同一个祖先进程的若干个进程中,FIFO管道可以克服这个问题

FIFO管道是一种文件类型,可以被创建在文件系统中,并设置相应的权限

多个进程可以通过分别以读/写方式打开该FIFO文件进行读/写,从而达到进行管道通信的目的

intmkfifo(char*pathname,mode_tmode)

FIFO管道的主要用途

在进程之间传输数据,但不便于使用无名管道的地方

在客户进程-服务器进程之间进行通信

XSIIPC(XSI进程间通讯)

有3种IPC被称为XSIIPC:消息队列、信号量和共享内存

XSIIPC没有使用文件系统名字空间,而是构造了自己的名字空间

这3种IPC具有类似的处理方式

消息队列

消息队列可以实现不同进程之间的消息传递

消息队列组织成一个链接表

消息的接收不一定按照先进先出的顺序,也可以按照消息的类型接收

操纵消息队列

打开或创建消息队列

intmsgget(key_tkey,intflag);

发送消息

intmsgsnd(intid,void*p,size_tnbytes,intflag);

接收消息

ssize_tmsgrcv(intid,void*p,size_tnbytes,longtype,intflag);

信号量

信号量是操作系统提供的一种重要的进程同步工具

Unix信号量实现了整型信号量的一个超集功能

信号量上的操作

信号量的操作主要包括3个方面

打开或创建信号量

信号量值操作

获取或者设置信号量属性

打开/创建信号量

首选需要得到一个key,这个key是通过一个全局唯一的名字生成的,可以通过调用ftok函数获得

key_tftok(char*path,intid);

然后通过得到的key打开或创建信号量,得到一个信号量集的标识

intsemget(key_tkey,intnsems,intflag);

信号量值操作

信号量值的操作也就是wait(P)操作和signal(V)操作

intsemop(intsemid,structsembufsemoparray[],size_tnops);

其中sembuf结构表示了如何操作信号量的值

semop具有原子性,要么执行所有的操作,要么什么也不做

sembuf结构体

str

您可能关注的文档

文档评论(0)

159****9610 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

版权声明书
用户编号:6044052142000020

1亿VIP精品文档

相关文档