2012-03-14 50 views
15

我正在阅读有关各种IPC机制。我试图找出场景,我们使用共享内存和我们使用命名管道(FIFO)的地方。何时使用管道vs何时使用共享内存

管道: 多个进程可以写入,但只有一个进程可以读取。写操作是原子的。

共享内存: 多进程可以读写。并且用户需要提供互斥以便读取&写入。

这是共享内存和管道应用的唯一区别吗?

+1

请注意,如果写入大小不超过PIPE_BUF,则只有原子。 – 2012-03-14 14:14:50

回答

35

本质上,管道 - 无论是命名还是匿名 - 都用于消息传递。有人向收件人发送一条信息,收件人可以收到该信息。共享内存更像是发布数据 - 有人将数据放入共享内存中,读者(可能很多人)必须使用同步,例如通过信号来了解有新数据的事实,并且必须知道如何读取内存区域来查找信息。

使用管道,同步过程非常简单,并内置于管道机制本身 - 当发生某些有趣的事情时,读取和写入操作将冻结并解冻应用程序。使用共享内存,异步工作更容易,并且只需一次检查新数据 - 但代价是更复杂的代码。另外,您可以获得多对多的沟通,但需要再次进行更多的工作。而且,由于上述原因,调试基于管道的通信比调试共享内存更容易。

一个小的区别是,fifos可以直接在文件系统中看到,而共享内存区域需要特殊的工具,如ipcs来管理,创建一个共享内存段,但是你的应用程序会死掉,并且不会自行清理(同样适用于信号量和许多其他需要与共享内存一起使用的同步机制)。

共享内存还可以让您更好地控制缓冲区和资源使用 - 在操作系统允许的范围内,您决定分配多少内存以及如何使用它。通过管道,操作系统可以自动控制事物,因此您再次失去了一些灵活性,但是可以放松很多工作。

最重要的一点总结:一对一沟通的管道,更少的代码和让操作系统处理事物,共享内存以进行多对多,更人工的控制,但是牺牲了更多的工作和更难调试。

+1

一些小的修正。管道也可以通过'pipe'系统调用匿名创建。共享内存也可以通过不私自'nmap'文件来驻留在文件系统中。 – johannes 2012-12-28 12:56:38

+1

FIFOs也支持多对一的通信(“摘要”只意味着一对一)。 – 2013-01-04 17:32:08

+0

@MarkRajcok虽然可能,但实际上许多使用管道的编写者并不是很有用,因为没有内置的机制来管理消息级的同步 - 无论所有编写者发送的内容是否会以不可预知的方式交织。即使实现了外部同步,但最好的做法是在发送每条消息时在写入器之间进行独占锁定,因为只有一个可以同时写入,所以这是无效的。 – 2013-01-04 20:20:56