一、进程间通信介绍
1. 进程间通信的目的
进程间通信就是进程之间的信息交流,交流的目的主要的:
数据传输:一个进程需要将它的数据发送给另一个进程
资源共享:多个进程之间共享同样的资源。
通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止 时要通知父进程)。
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另 一个进程的所有陷入和异常,并能够及时知道它的状态改变
2. 进程间通信的手段
我们都知道,进程之间具有独立性,每个进程是相对独立的,因此要实现进程间的通信,我们就要想办法让不同的进程看到同一份数据,并且可以对这个数据进行访问和读写,这样就是实现了通信
进程通信的发展:管道 ——> System V进程间通信 ——> POSIX进程间通信
二、管道
1.匿名管道
1.1 理解
我们要让两个进程看到同一份数据,可以采用匿名管道的方式,匿名管道实际上就是一个OS提供的一个内存文件,让父进程建立对这个文件的读写端(以读和以写的方式分别打开这个文件),然后再创建子进程,此时子进程同样可以看到该文件,关闭一方读端,关闭另一方写端,就形成了一个用于单向传递信息的文件,这种OS提供的临时文件被称为管道文件
1.2 使用方式
函数声明:int pipe(int fd[2]);
函数头文件:#include<unistd.h>
父进程可以通过调用pipe函数去创建管道文件,pipe函数内部做的工作实际就是建立一个读写端的管道文件,并且以输出型参数的形式返回读端和写端的fd,fd就是文件的文件描述符,在使用系统调用接口去对文件进行读写时,就是根据返回的这个fd去操作的,其中,下标0位置放的是读端的fd,下标1位置放的是写端的fd
以这种方式建立的管道文件,这个文件时操作系统帮我们建立的,我们并不知道该管道文件的名字,因此被称为匿名管道
1.3 管道通信的特点
1. 单向通信
2. 管道的本质是文件,因为fd的生命周期随进程结束,管道的生命周期也是随进程的
3. 管道通信是根据父进程创建子进程的方式,使得父子进程看到同一份数据,这种方式就注定了管道通信通常都是用来进行具有“血缘”关系的进程之间的通信
4. 由于是用pipe函数打开的管道,并不清楚管道文件的名字,因此这种方式被叫做匿名管道
5. 在管道通信中,写入端的写入次数和读取次数,不是严格匹配的,两者没有强相关
6. 具有一定的协调能力,让读写端具有一定的步骤进行,自带同步机制,体现在以下四种情况:
1.4 简单样例
通过一个简单的样例测试匿名管道的使用,我们希望建立一个父进程控制多个子进程,让子进程根据父进程的指令去执行不同任务的小demo
构建结构
先通过创建匿名管道,然后创建子进程的方式,去创建单向管道通信的结构,然后多次循环的去创建,但是这里有一个非常容易忽略的bug,就是通过这种循环创建的方式创建的结构,实际在第二次创建的子进程除了和匿名管道有读写端的链接,它实际还打开着对上一个管道的写段,这是通过父进程继承下来的
Q