跨平台IPC

78

我正在寻找可能的IPC机制建议,它们需要满足以下条件:

  • 跨平台 (至少支持Win32和Linux)
  • C++以及最常见的脚本语言(perl、ruby、python等)中实现简单
  • 从编程角度看,易于使用

我的选择有哪些?我正在Linux下编程,但我希望将来所写的代码可以在其他操作系统上移植。我曾考虑使用套接字、命名管道或类似DBus的东西。

16个回答

57

就速度而言,最好的跨平台进程间通信(IPC)机制将是管道(pipes)。不过,这假定你想要在同一台机器上进行跨平台IPC。如果你想要与远程机器上的进程通信,那么你需要考虑使用套接字(sockets)。幸运的是,至少对于TCP来说,套接字和管道表现出几乎相同的行为。虽然它们的设置和连接API不同,但它们都只是像数据流一样工作。

然而,困难的部分并不是通信渠道,而是你传递的消息。你真的希望找到一个可以为你执行验证和解析的东西。我建议看看Google的 Protocol Buffers 。你基本上创建一个规范文件,描述你想在进程之间传递的对象,然后有一个编译器会生成符合规范的对象的读写代码,支持多种不同语言。它比尝试自己设计消息协议和解析器要容易得多(也更少错误)。


当您想要与已经启动和运行的进程通信时,管道是否是答案?为此,应该使用套接字,对吧? - donatello
@donatello,我想这是命名管道 - moooeeeep
3
想要补充的是,现在已经过去了10年!gRPC也已经开源,它是基于Protocol Buffers的Google RPC协议。 - Thomas

16

如果您使用的是C++,可以查看Boost IPC

否则,如果与脚本语言进行交互非常重要,您最好使用文件、管道或套接字,甚至使用更高级别的抽象,例如HTTP。


11
如果你想要一个便携、易于使用、多语言和LGPL的解决方案,我会推荐你使用ZeroMQ:
  • 惊人的快速度,几乎是线性可扩展的,而且仍然简单。
  • 适用于简单和复杂的系统/架构。
  • 提供非常强大的通信模式:REP-REP,PUSH-PULL,PUB-SUB,PAIR-PAIR。
  • 你可以配置传输协议,使其在线程(inproc://),进程(ipc://)或计算机之间({tcp|pgm|epgm}://)传递消息更加高效,并智能地选择一些选项来削减在VMware虚拟机之间运行连接时的协议开销(vmci://)。

对于序列化,我建议使用MessagePack或Protocol Buffers(其他人也已经提到了),具体取决于你的需求。


10

为什么不考虑使用D-Bus呢?它是一个非常简单的消息传递系统,可在几乎所有平台上运行,并专门设计用于增强鲁棒性。目前,它得到了几乎所有脚本语言的支持。

http://freedesktop.org/wiki/Software/dbus


1
D-Bus根据您选择的Academic Free License版本2.1或GNU General Public License版本2向您授权许可。GPL可能不适合。 - Nick
@Nick,D-Bus许可证只会影响他如果他尝试修改D-Bus。只要他仅将其用于通信,那么D-Bus是否采用GPL许可证并不重要。 - SystematicFrank
1
除了许可证之外,D-BUS 也有一些缺点: 1)它不是特别快 2)你需要运行一个守护进程才能使用 D-BUS(据我所知) - kralyk
11
我认为将 D-Bus 描述为 "非常简单" 不太准确,它实际上相当复杂。 - kralyk
2
@kralyk,你不需要运行dbus守护进程,只需要有一个服务器端和一个客户端,这样一方就可以连接到另一方。DBus的概念相当简单,但是直接使用libdbus可能会相当复杂,这就是为什么你最好使用高级绑定的原因。 - remmy
显示剩余3条评论

8

您可以尝试YAMI,它非常简单实用,可移植性强,并且提供了几种语言的绑定。


6

我建议您使用plibsys C库。它非常简单、轻量级且跨平台。采用MIT许可证发布。它提供了以下功能:

  • 命名的系统范围共享内存区域(System V、POSIX和Windows实现);
  • 用于访问同步的命名系统范围信号量(System V、POSIX和Windows实现);
  • 基于共享内存和信号量的命名系统范围共享缓冲区实现;
  • 带有IPv4和IPv6支持的套接字(TCP、UDP、SCTP)(UNIX和Windows实现)。

这是一个易于使用的库,文档相当不错。由于它是用C语言编写的,您可以轻松地从脚本语言中进行绑定。

如果您需要在进程之间传递大型数据集(特别是速度至关重要时),最好使用共享内存来传递数据本身,并使用套接字通知进程数据已准备就绪。您可以按照以下方式进行操作:

  • 一个进程将数据放入共享内存段,并通过套接字向另一个进程发送通知;由于通知通常非常小,因此时间开销很小;
  • 另一个进程接收通知并从共享内存段读取数据;之后它发送一个通知,告诉第一个进程数据已经被读取,以便它可以提供更多的数据。

这种方法可以以跨平台的方式实现。



5

那么Facebook的Thrift怎么样?

Thrift是一个用于可扩展跨语言服务开发的软件框架。它结合了一个软件堆栈和一个代码生成引擎,以构建能够在C ++、Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、Smalltalk和OCaml之间高效无缝工作的服务。


2
听起来好像有很多额外的开销。 - d-_-b

5

我认为您需要基于套接字(socket)的解决方案。

如果您需要远程过程调用(RPC)而不仅仅是进程间通信(IPC),我建议使用类似于XML-RPC/SOAP的技术,其可以通过HTTP运行,并且可以被任何语言使用。


是的,我想我所说的RPC是指在不同操作系统上运行的两台机器之间的机器间通信,而IPC则是指在一台机器上的两个进程之间的通信(例如,在Linux和Windows上进行构建时的源级跨平台)。 - Douglas Leeder

4
分布式计算通常很复杂,因此建议您使用现有的库或框架,而不是重新发明轮子。先前的帖子已经列举了一些这样的库和框架。根据您的需求,您可以选择非常低级(如套接字)或高级框架(如CORBA)。不能有一个通用的“使用此”答案。您需要学习分布式编程,然后会更容易为工作选择正确的库或框架。
存在着一个广泛使用的用于分布式计算的C++框架叫做ACE,以及基于ACE构建的CORBA ORB TAO。关于ACE有非常好的书籍可供参考http://www.cs.wustl.edu/~schmidt/ACE/,您可以看看。注意!

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