为什么进程间需要通信?
1
、数据传输
一个进程需要将它的数据发送给另一个进程。
2
、资源共享
多个进程之间共享同样的资源。
3
、通知事件
一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件。
4
、进程控制
有些进程希望完全控制另一个进程的执行(如
Debug
进程),此时控制进程希望能够拦截另
一个进程的所有操作,并能够及时知道它的状态改变。
*******************************************************************************************************************
进程间通信的数据交换发生在操作系统在内核中开辟的一块缓冲区。所以在读写过程中会发生两次数据的拷贝(写端在写完数据后,需要把数据拷贝到内核区;读端在读数据时,需要从内核区把数据拷贝到读端,才能读)
管道是一个文件,是用环形队列实现的,管道通信适用于父子进程(有血缘关系的)
*******************************************************************************************************************
一、管道的创建
返回值:
成功返回0,失败返回-1。
*******************************************************************************************************************
二、管道通信的过程:
(1)父进程调用 pipe 开辟管道,得到两个文件描述符指向管道的两端;
(2)父进程调用 fork 创建子进程,子进程也会有两个文件描述符(继承父进程的文件描述符)指向同一管道;
(3)两个进程一个关闭读端,一个关闭写端,这样就可以保证一个进程往管道里写,另一个进程从管道里读。
*******************************************************************************************************************
二、使用管道的限制
(1)管道只能实现单项通信
*******************************************************************************************************************
三、使用管道,应注意
(1)
如果所有指向管道
写端
的文件描述符
都关闭
了
(
管道写端的引用计数等于
0),
而
仍然有
进程 从管道的读端读数据
,
那么管道中
剩余的数据都被读取
后
,
再次
read
会返回
0
,
就像
读到文件末尾一样。
(2)如果有指向管道
写端
的文件描述符
没关闭
(
管道写端的引用计数大于
0),
而
持有管道写
端的 进程也没有向管道中写数据
,
这时有进程从管道读端读数据
,
那么
管道中剩余的数
据都被读取后
,
再次
read
会阻塞
,
直到管道中有数据可读了才读取数据并返回。
(3)
如果所有指向管道
读端
的文件描述符
都关闭
了
(
管道读端的引用计数等于
0),
这时有进
程向管道的写端
write,
那么该进程会收到信号
SIGPIPE,
通常会导致进程异常终止
。
(4)
如果有指向管道
读端
的文件描述符
没关闭
(
管道读端的引用计数大于
0),
而持有管道读
端的 进程也
没有从管道中读数据
,
这时有
进程向管道写端写数据
,
那么在管道被写满时
再 次
write
会阻塞
,
直到管道中有空位置了才写入数据并返回。
*******************************************************************************************************************
四、用管道实现进程间通信