进程间通信

一、理解通信

进程需要通过通信来协同或传递数据(通知就绪,传单纯数据,控制信息...)

进程通信的前提:先让不同的进程看到同一份操作系统资源(一段内存)

1、一定是某个进程要通信,让OS创建一个共享资源。

2、OS要提供很多系统调用接口。

3、共享资源不同,系统调用接口不同导致进程间通信的种类不同。

二、进程通信常见方式

1、system V 本地通信(不常用)

(1)消息队列

(2)共享内存

(3)信号量

2、管道

(1)匿名管道

特点

只用于具有血缘关系的进程之间通信,常用于父子间通信。

问题

1、为什么父子进程会向同一个显示器终端打印数据?

进程创建默认打开三个标准输入输出文件0,1,2,本质就是父进程bash打开的,所以之后的进程都能看到三个打开的文件。

2、子进程关闭文件为什么父进程不受影响?

文件中有引用计数,只有文件引用计数 == 0,才会释放文件资源。

注意

1、管道文件只允许单向通信。

2、管道文件用于两进程间通信,不要刷新到磁盘。

3、父子进程要保证管道文件单向通信就要关闭不要的读写文件,那为什么一开始都要打开?要让子进程继承下去。

创建匿名管道

函数 int pipe(int pipefd[2])

pipefd[2]:输出型参数,pipefd[0]表示读文件,pipefd[1]表示写文件。

成功创建返回0,失败返回-1

本质就是复用 open() 函数。

创建时不要文件路径,文件名,就是创建匿名管道文件。

要双向通信就创建两个管道文件。

举例

进程池

父进程提前创建一批子进程,由于父进程写端打开,如果不写入读端会被阻塞,这样就达到了父进程只要一把任务写道管道,子进程就能接收到运行,这样就不用到要用子进程时创建,节省资源。

但是会出现一种情况:

由于每一次创建子进程都会复制父进程的写端,就导致子进程会有写端,这样就不符合父进程写入,子进程读入的形式,所以每次创建子进程时要遍历管道数组,把写端关闭。

(2)命名管道

理解

两个毫不相干的进程之间打开同一个文件,一个读,一个写,这个文件就是管道文件。

为什么要命名?

用于两个毫不相干的进程之间通信,标识管道文件的路径是找到文件的办法。

对于读端而言,如果我们打开文件但写端未打开,就会阻塞在open()函数,直到写端打开,匿名管道一开始就是打开的。这其实也是一种进程同步。

创建命名管道

pathname:文件路径

mode:文件权限

删除指定文件

删除指定路径下的文件。

(3)管道的4个特点

a、管道内部自带同步机制(多执行流执行代码时具有明显顺序性)

b、文件的生命周期时随进程的

c、管道文件在通信时是面向字节流(写入与读入的次数不是一一对应的)

d、管道的通信模式是特殊的半双工模式

全双工与半双工:两者既能写入又能读入,半双工指双方不能同时写入或读入,全双工可以同时,由于管道一个进程只能写入或读入,所以是特殊的半双工模式。

(4)管道的4种情况

a、如果管道内部为空,写端未关闭(不写入),读条件不具备,读进程就会阻塞。

b、如果管道写满,读端未关闭(不读入),写进程就会被阻塞。

c、管道一直在读,但是写端已经关闭,read() 返回0,表示读到文件末尾。

d、管道一直在写,但是读端已经关闭,操作系统用13号信号杀死进程,出现异常。

当写入管道的大小小于4096字节就是原子的安全的。

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值