- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 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)