一、无名管道(pipe)

也成匿名管道,是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

具有如下特点:

1、半双工。即数据只能在一个方向上流动。

2,只能在具有公共祖先的进程间使用。通常一个管道由一个进程创建,然后该进程调用fork,然后父子进程间就可以应用该管道。

3,数据从管道的一端写入,从另一端读出。一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加管道缓冲区的末尾,并且每次都是从缓冲区的头部读出。

4,没有名字

5,管道的缓冲区是有限的。管道存在于内存中,在管道创建时,为缓冲区分配一个页面大小。

6,管道传送的数据是无格式的。

7,单独构成一个独立的文件系统。管道对于管道两端的进程而言就是一个文件,但他不是变通的文件。而是构成一种文件系统,并且只存在于内存中。

8,写入管道的数据读完后就从管道消失。

一般,一个进程由pipe()创建管道后,一般再fork一个子进程,然后通过管道实现父子进程的通信。

参考:http://www.rosoo.net/a/201105/11672.html

二、有名管道(named pipe)

有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

无名管道只能连接亲缘关系进程,由进程创建并由最后一个进程关闭。而命名管道可以连接不相关的进程。它是个FIFO先进先出队列,即使没有进程,命名管道依然可以存在,它不依赖于进程。前端进程将字节写入队列,另一端进程从队列头部移出字节。前端再写新数据数据,它没有竞争的问题,在没有超过管道最大长度的时候,read和write都是原子操作,先将管道清空,然后再将管道写满,在读者和写者联通之前系统内核将进程挂起。

三、共享内存(shared memory)

是进程间最简单的通信方式之一。共享内存允许两个或更多个进程访问同一内存,就如malloc()函数向不同的进程返回了同一个物理内存区域的指针,当一个进程改变这块物理内存的内容时,其他进程就可以察觉到。实际上这段共享内存由一个进程创建,但多个进程都可以访问。

因为数据不需要来回复制,所以共享内存是最快的进程间通信(IPC) 方式,它是针对其他进程间通信方式运行效率低而专门设计的。

共享内存可以通过mmap()映射普通文件机制实现,也可以通过系统V共享内存机制实现。系统V共享内存是以文件的形式在特殊文件系统shn中,通过shmget可以创建或获得共享内存的标识符。取得共享标识符后,要通过shmat将这个内存区映射到本地的虚拟空间。

为了更安全的通信,例如如果读取是在服务器向内存中写数据的时候进行的,有可能既读到旧数据又读到新数据。它往往信号量(灯),配合使用,来实现进程间的同步和通信。
尽管共享内存是同一个计算机中进程间通信的最快捷方式,但局限也在于此,即共享内存的各进程必须处于处于同一个计算机系统中,有物理内存可以共享才行。

四、信号量(其实是共享内存的辅助机制,严格来说不是一种独立的进程间通信方式)

信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

也就是说是进程间以及同一进程不同线程的同步手段。
五、信号( sinal )

信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

六、 消息队列( message queue )

消息队列是消息的链接表,包括Posix信息队列和系统V消息队列。存放在内核中并由消息队列标识符标识。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程可以从队列中读走消息。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

七、套接字( socket )

更为一般的通信机制,最大特点是可用于不同机器之间的通信。


总结,1.文件和命名管道消耗操作多。2.文件和共享内存是无连接的3.命名管道和共享内存只能在本机中使用4.使用共享内存和文件要比使用管道麻烦,要处理竞态。
注:ATT的贝尔实验室对早期的简称间通信方式进行了改进,形成了系统V。以上通信方式可适用于Windows和linux等平台。