【问题标题】:Simple IPC between C++ and Python (cross platform)C++ 和 Python 之间的简单 IPC(跨平台)
【发布时间】:2011-10-18 09:58:02
【问题描述】:

我有一个在后台运行的 C++ 进程,它将不频繁地生成“事件”,而在同一机器上运行的 Python 进程将需要接收。

  • C 端的代码需要尽可能的轻量级。
  • Python 端是只读的。
  • 实施必须是跨平台的。
  • 发送的数据非常简单。

我有什么选择?

谢谢

【问题讨论】:

  • 您的程序在什么操作系统下运行?基于管道的 IPC 在类 Unix 机器上很容易实现。
  • “C 面”是错字吧?

标签: c++ python cross-platform ipc


【解决方案1】:

您的数据有多复杂?如果它很简单,我会将其序列化为字符串。如果它比较复杂,我会使用 JSON。 TCP 是一种很好的跨平台 IPC 传输。既然你说这个IPC稀有那么性能不是很重要,TCP+JSON就可以了。

【讨论】:

    【解决方案2】:

    Google 的protobuf 是一个很棒的程序间RPC 库。它为PythonC++ 生成绑定。

    如果您需要分布式消息传递系统,您还可以使用 RabbitMQzeromqActiveMQ 之类的东西。有关消息队列库的讨论,请参阅 this question

    【讨论】:

    • RabbitMq 是火箭筒,而 ZeroMq 是苍蝇拍;)
    • OP 没有说明是否需要“火箭筒”,所以我提出了我认为最受欢迎的一个。我已经编辑了我的答案以包括 zeromq 和 ActiveMQ,并指出了关于该主题的另一个 SO 问题。
    • 我认为protobuf 只是一个序列化库,用于消息本身的可移植传输。它似乎没有为 RPC 调用和 IPC 提供任何机制。
    【解决方案3】:

    使用zeromq,就这么简单。

    【讨论】:

    • 不错的项目,有很好的文档。感谢您指出这一点!
    • 看起来确实很棒。而且它看起来确实便携、灵活且快速。
    【解决方案4】:

    另一种选择是使用 ctypes 模块从 Python 代码中调用 C 代码,而不是分别运行这两个程序。

    【讨论】:

    • C进程是一个守护进程,一直在后台运行。
    【解决方案5】:

    zeromq -- 仅此而已。将消息编码为字符串。

    但是,如果您想从库中获取序列化,请使用protobuf,它将为 Python 和 C++ 生成类。您在任一端使用 SerializeToString() 和 ParseFromString() 函数,然后通过 ZeroMq 管道传输字符串。

    问题已解决,因为我怀疑任何其他解决方案都更快,而且任何其他解决方案都不会像接线和易于理解那样简单。

    如果想为 rpc 使用特定的系统原语,例如 Windows 上的命名管道和 unix 上的 Unix 域套接字,那么您应该查看Boost::ASIO。但是,除非您具有 (a) 网络背景,并且 (b) 非常了解 C++,否则这将非常耗时

    【讨论】:

    • +1 表示多个选项。并指出protobuf只是序列化方面的解决方案。
    • 我选择 zeromq 是因为服务端实现是 12 行代码!!如果我不需要,我不喜欢依赖,但 zeromq 是个例外。 :)
    • 是的,zeromq 是专为您的用例而设计的。它非常原始且非常容易理解。不过,它的原始性是健壮的,因为您可以从中实现更复杂的消息传递结构。在我的工作中,我选择在 boost:ASIO 之上实现我自己的 RPC 系统,因为我需要上面提到的系统原语。
    • Zeromq 是最糟糕的。我已经用 ZeroMQ 做到了这一点,现在正在切换到其他任何东西。 ZeroMQ 根本没有失败的概念。如果您尝试发送消息并且您的流程失败,则无法判断。它只会继续尝试永远发送。还有许多其他问题,失败是完全不透明的,因此也无法重试。
    • @ghostbust555 我已经很久没有使用 zeromq 了。 “根本没有失败的概念”,换句话说,“一劳永逸”,“一劳永逸”的消息传递并没有错。如果需要,您还可以在 zeromq 之上构建故障机制。话虽如此,这些天我可能会倾向于 GRPC,但如果我没记错的话,它确实有相当大的 python 依赖足迹。
    【解决方案6】:

    我会说您创建一个 DLL 来管理两者之间的通信。 python 将加载 DLL 并调用 getData() 等方法,DLL 将依次与进程通信并获取数据。 这应该不难。 您也可以使用 XML 文件或 SQLite 数据库或任何数据库来查询数据。守护进程将更新数据库,Python 将继续查询。可能有一个字段用于指示 DB 中的数据是否已由守护程序更新,然后 Python 将查询。 当然,这取决于性能和准确性因素!

    【讨论】:

    • 因为我不想飞到日本去拿寿司,因为我可以拿起电话把它送到。 :)
    • @Stefano 批评很明显......我反对非跨平台解决方案(见标签)。
    【解决方案7】:

    您可以为此使用 Google GRPC

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-14
      • 2010-09-20
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-16
      相关资源
      最近更新 更多