进程间通信建议

10

我正在寻找一种轻量级、快速且易于处理Linux机器上多个程序间进程通信的方法。

目前,我考虑使用Named Pipe,因为它是由操作系统自己提供的。那么在性能和可用性方面是否存在缺陷?

Shared Memory会更好吗?

我不认为我需要一个超级复杂的框架。

请指引我正确的方向,谢谢!


更新: 我想要构建一个小型程序(守护进程),告诉其他程序(它自己启动的)暂停、报告其状态,停止等。

因此,其他程序应该被通知有新命令正在等待它。对于这个需求,使用管道不是最理想的方法,对吗?

6个回答

11

如您所见,您可以使用以下方法进行进程间通信:

  • 共享内存
  • 命名管道
  • TCP/UDP套接字(在本地也可用)

共享内存具有性能优势,因为在发送/接收消息时没有缓冲区。但是,您必须与另一个IPC同步数据交换。它可以是IPC信号量或...... 命名管道或套接字。

当性能不是主要目标时,我倾向于选择套接字,因为它们的使用简单,并且可以扩展到计算机之间的通信。

最好的方法是使用类来抽象化您的通信,该类可以在两个进程在同一台计算机上时使用共享内存,并使用套接字否则。然后,您必须选择UDP和TCP之间的选择;-)

对于同步/缓冲器交换,请优先选择TCP,因为它更可靠。

我不使用命名管道,因为我更喜欢套接字,因为它具有使用计算机间通信的可能性,当然您可以找到许多可移植的套接字库......

我的2美分

编辑:

对于同步,共享内存可能不是最好的工具。在您的情况下,可以通过共享小内存空间,并为每个等待命令的进程分配一个空间来使用它。您可以轮询任何即将到来的命令,也可以使用共享信号量。最快的方法是您的进程等待命名信号量并读取共享的mem空间以获得其命令/参数。使用命名管道肯定更简单,但速度不那么快。您当然不需要那么快吧?无论如何,将其抽象化为模拟您的交换协议的类,并尝试这两种方式:-)


我希望有一些不需要使用TCP协议栈开销的东西,因为需要最佳性能。我们将使用TCP协议与其他机器进行通信,但在本地,更快的东西是理想的。 - brandstaetter
1
@brandstaetter:在这种情况下,共享内存是最好的选择。数据越大,性能提升越明显。其他IPC(和套接字)需要缓冲,即使它们已经被优化了。使用共享内存可以确保没有缓冲开销。我们使用共享内存进行图像交换。同步可以通过命名管道或(本地)套接字完成,比共享信号量更易于管理(并且更具可移植性)。甚至可以根据您的数据/交换协议而不依赖它。 - neuro
@Matthieu:谢谢。这总是证明了一件好事,特别是在处理外部接口时 :-) - neuro

5
Boost有一个不错的InterProcess库,它是跨平台且相当直观的。
虽然我只是玩弄了一下,但可能还有更好的选择。
然而,如果您真的不需要共享内存,我建议使用消息传递方法。这样可以避免死锁和竞态条件。管道原理真的很棒,甚至可以实现懒惰行为,这可能会根据手头的问题节省大量处理时间!

那看起来很有趣。我会好好研究的。我总是忘记查看boost库。 - brandstaetter

4
一个不错的选择是使用socketpair,非常快速和高效。

2

呃,可能有些过度设计了,如果还没有安装或设置的话,我猜可能会比较难设置? - neuro

1

我会使用Unix套接字或一些封装它们的库。Unix套接字非常容易使用。

另一方面,如果您需要报告固定大小的状态信息,您可以让子进程将其写入文件中(假设它很小,您不会fsync它,因此它不会产生重要的IO工作负载)。


+1:为什么不用文件呢?虽然不是最好的同步方式,但你可以使用标记/计数器进行同步。 - neuro

1

如果您想从原语开始构建软件,共享内存和信号量是最快且最透明的选择。

命名管道与管道并没有太大区别,适用于一对进程之间的通信,而不是服务器和多个客户端之间的通信。

如果您想在现有基础设施上构建应用程序,dBus 是一个选项。

如果您希望将应用程序移动到网络上的其他主机上,套接字通信是一种多才多艺且可扩展的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接