管道和FIFO(命名管道)
最适合在进程之间实现生产者/消费者的交互。有些进程向管道写入数据,而另外一些进程则从管道中读出数据。
信号量
消息队列
允许进程在预定义的消息队列中读和写消息来交换消息(小块数据)。linux内核提供两种不同消息版本:System V IPC和POSIX消息。
共享内存区
允许进程通过共享内存块来交换信息。在必须共享大量数据的应用中,这可能是最高效的通信方式。
套接字
允许不同计算机上的进程通过网络交换数据。套接字还可以用作相同主机上的进程之间的通信工具;例如,X window系统图形接口就是使用套接字来允许客户端和X服务器交换数据的。
管道
管道是进程之间的一个单向数据流:一个进程写入管道的所有数据都由内核定向到另一个进程,另一个进程由此就可以从管道中读取数据。
在unix的命令shell中,可以使用“|”操作符来创建管道。
eg:$ls | more 第一个进程(执行ls程序)的标准输出被重定向到滚到中;第二个进程(执行more程序)从这个管道中读取输入。
管道被看做是打开的文件,但在已安装的文件系统中没有相应的映像。可以使用pipe()系统调用来创建一个新管道,这个系统调用返回一对文件描述符;然后进程通过fork()把这两个描述符传递给它的子进程,由此与子进程共享管道。进程可以在read()系统调用中使用第一个文件描述符从管道中读取数据,同样也可以在write()系统调用中使用第二个文件描述符向管道中写入数据。
POSIX之定义了半双工管道,因此即使pipe()系统调用返回两个描述符,每个进程在使用一个文件描述符之前仍得把另一个文件描述符关闭。如果所需要的是双向数据流,那么进程必须通过两次调用pipe()来使用两个不通管道。linux每个管道文件描述符仍然都是单向的,但那时在使用一个描述符之前不必把另一个描述符关闭。
FIFO
虽然管道是一种十分简单、灵活、有效的通信机制,但它们有一个主要特点,也就是无法打开已经存在的管道。这就使得任意两个进程不可能共享同一个管道,除非管道由一个共同的祖先进程创建。
为了突破这种限制,Unix系统引入了一种称为命名管道(nemed pipe)或者FIFO的特殊文件类型。FIFO非常类似于管道:在文件系统中不拥有磁盘块,打开的FIFO总是与一个内核缓冲区相关联,这一缓冲区中临时存放两个或多个进程之间交换的数据。
在linux2.6中,FIFO和管道几乎是相同的,并使用相同的pipe_inode_info结构。事实上只有两点主要差别:
FIFO索引节点出现在系统目录树上而不是pipefs特殊文件系统中。
FIFO是一种双向通信管道;也就是说,可能以读/写模式打开一个FIFO。
System V IPC
IPC是进程间通信(Interprocess Communication)的缩写,通常指允许用户态进程执行下列操作的一组机制:
通过信号量与其他进程进行同步。
向其他进程发送信息或者从其他进程接收信息。
和其他进程共享一段内存区。
IPC数据结构是在进程请求IPC资源(信号量、消息队列或者共享内存区)时动态创建的。每个IPC资源都是持久的:除非被进程显示的释放,否则永远驻留在内存中(直到系统关闭)。IPC资源可以由任一进程使用,包括那些不共享祖先进程所创建的资源的进程。
根据新资源是信号量、消息队列还是共享内存区,分别调用semget()、msgget()或者shmget()函数创建IPC资源。
注意,进程之间另一个通信通道的存在并不基于IPC。
IPC信号量
IPC信号量与内核信号量非常相似:二者都是计数器,用来为多个进程共享的数据结构提供受控访问。
如果受保护的资源是可用的那么信号量的孩子就是正数;如果受保护的资源现在不可用,那么信号量的值就是0。要访问资源的进程试图把信号量的值减一,但是,内核阻塞这个进程,直到在这个信号量是的操作产生一个正值。当进程是受保护资源时,就把信号量的值增加一;在这样处理的过程中,其他所有正在等待这个信号量的进程就都被唤醒。
IPC消息
进程之间可以通过IPC消息进行通信。进程产生的每条消息都被发送到一个IPC消息队列中,这个消息一直存放在队列中直到另一个进程将其读走为止。
消息是由固定大小的首部和可变长度的正文组成的,可以使用一个整数值(消息类型)标识消息,这就允许进程有选择地从消息队列中获取消息。只要进程从IPC消息队列读出一条消息,内核就把这个消息删除;因此,只能有一个进程接收一条给定的消息。
IPC共享内存
最有用的IPC机制是共享内存,这种机制允许两个或多个进程通过把公共数据结构放入一个共享内存区(IPC shared memory region)来访问他们。如果进程要访问这种存放在共享内存区的数据结构,就必须在自己的地址空间中增加一个新内存区,它将映射与这个共享内存区先关的页框。这样的页框很容易地由内核通过请求调页进行处理。
POSIX消息队列
POSIX标准(IEEE Std 1003.1-2001)基于消息队列定义了一个IPC机制,即使大家知道的POSIX消息队列。它很像之前的IPC消息,但是POSIX比老的队列具有许多优点:
1.更简单的基于文件的应用接口。
2.完全支持消息优先级(优先级最终决定队列中消息的位置)。
3.完全支持消息到达的异步通知,这通过信号或是线程创建实现。
4.用于阻塞发送与接收操作的超时机制。
以上内容来自《深入理解LINUX内核》一书。