进程间通信的概念(IPC:InterProcess Communication):每个进程各有不同的用户地址空间,如何一个进程的全局变量是不能被别的进程看见的,所以进程间通信都要经过内核,在内核中开辟一个缓存区,这个缓存区是所有与缓存区相关的进程都能访问的。进程1把数据从用户空间拷到内核缓存区,进程2再从缓存区把数据读到自己的用户空间。内核提供的这种机制就叫做进程间通信。
一.匿名管道(pipe):
匿名管道是一种半双工(在同一信道上,同一时刻只能接受或者发送数据)的通信方式,数据只能单向流动。匿名管道通过文件描述符进行操作,子进程会继承父进程的文件描述符。所以匿名管道只能用于有血缘关系的进程的进程间通信。
管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道。只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
创建匿名管道的过程:
父进程通过pipe函数创建一个管道,得到两个文件描述符指向管道的两端。
父进程调用fork函数创建一个子进程,子进程会继承父进程PCB中的一部分数据,所以子进程也有两个文件描述符指向管道的两端。
父进程关闭管道读端,子进程关闭管道写端(close函数关闭读/写端)。
注:应该先写入数据再进行读操作
注:管道是以环形队列实现的,是以流的形式传递数据的。
管道的局限:
管道的主要局限性正体现在它的特点上:只支持单向数据流;只能用于具有亲缘关系的进程之间;没有名字;管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配一个页面大小);管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、或记录)等等;
二.命名管道(有名管道 或FIFO):
匿名管道,由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了有名管道(FIFO)。有名管道不同于匿名管道之处在于它提供了一个路径名与之关联,以有名管道的文件形式存在于文件系统中,这样,即使与有名管道的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过有名管道相互通信,因此,通过有名管道不相关的进程也能交换数据。值的注意的是,有名管道严格遵循先进先出(first in first out),对匿名管道及有名管道的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek()等文