进程间通信

时间:2009-05-03 02:23:00

标签: ipc

使用文件进行进程间通信的优缺点是什么?让我举一些背景介绍我在问这个问题的背景。

问题是具有一些约束的经典生产者消费者问题。生产者是在一组机器上运行的协同进程集,并使用广播相互通信。每个进程都具有它所知道的本地用户,并且还允许其他进程通过上述广播机制了解它们。到目前为止,广播/共享的状态信息没有被保留,但现在需要它。

这个系统已经在生产上运行了多年,现在支持成千上万的用户,人们可以理解为添加任何额外的依赖关系以增加对持久性的支持是非常担心的。我们选择的路径是在现有进程中生成一个新线程,该线程将本地流量写入文件系统上的文件,然后由新进程读取(让我们称之为消费者)并保持不变。我们用这种方法看到的优点是:

  1. 我们免费获得持久性。如果我们将其写入文件系统,那么新进程会出现问题,我们不会丢失任何本地流量。只要消费者知道它停在哪里,只要它出现,它就可以开始处理数据。
  2. 使用排队库的普通旧unix文件IO没有学习曲线。
  3. 最大的优点是我们根本不会影响当前的生产者进程,除了文件写入的新线程。
  4. 这种方法的一些问题是:

    1. 文件锁定和争用及其对性能的影响。
    2. 确保刷新写入缓冲区,并且只有在将完整事件写入文件后,生产者才会释放文件锁定。消费者应阅读不完整的记录。
    3. 思考?这种方法是否天真,我们是否应该为使用现成的持久性队列库的加速时间支付初始成本?这里的要点是我们希望对当前进程产生最小的影响,并且不对其添加任何依赖性。

1 个答案:

答案 0 :(得分:1)

我最近遇到了这个选择,并考虑了解Berkeley DB使用其队列机制。但最终我决定使用Posix semaphores来使用Unix文件系统和编写我自己的原子队列原语。如果所有进程都在一台机器上,这很容易。原子放置函数大约是十几行代码;原子获取,因为它必须等待队列是空的,大约是大小的三倍。

我的建议是你设计一个隐藏这些细节的原子队列API 。 (遵循Parnas关于使用接口来隐藏可能会改变的设计细节的建议的经典示例。)您可以使用普通的Unix文件I / O来执行API的第一个版本。然后你可以尝试锁定,Berkeley DB或信号量等变体 - 所有这些都具有“对当前过程的最小影响”。

在尝试某些操作之前,您不会知道性能影响。实际文件系统上的文件锁定非常好; NFS上的文件锁定是一个熊。