在长时间运行的 c 进程和 python 之间进行双向 IPC 的最佳方法是啥?
Posted
技术标签:
【中文标题】在长时间运行的 c 进程和 python 之间进行双向 IPC 的最佳方法是啥?【英文标题】:what is the best way to do bidirectional IPC between a long-running c process and python?在长时间运行的 c 进程和 python 之间进行双向 IPC 的最佳方法是什么? 【发布时间】:2012-06-29 13:48:09 【问题描述】:我有一个现有的 C 进程,它可以接受一个文本输入并生成一个图像文件。 由于它与外部系统的接口,此 C 过程具有较高的设置/拆卸成本。 一旦设置/拆卸发生,从文本中实际生成图像几乎是瞬时的。
我的计划是守护 C 进程,因此它将无限循环地接收文本并生成图像文件,同时保持与外部系统的连接。
我还将在 python 中编写一个小型客户端程序,它将与守护程序接口以发送文本/接收图像。
目标操作系统是 unix。
问题是,在这种情况下,在 python/C 之间进行双向 IPC 的最佳方法是什么? 我应该只打开一个 unix 域套接字并来回发送打包的结构,还是应该查看 Apache Thrift 或 protobuf 之类的东西?
更新:
保持简单,打开一个unix域套接字
【问题讨论】:
我会选择最简单的解决方案来完成这项工作。文件系统中某个知名位置的一对命名管道可能是最省事的。您只需处理标准文件命令。 是的,你应该做出这个答案,所以我可以接受它 【参考方案1】:我认为套接字是通往这里的路。在 Unix 上,我推荐使用 AF_UNIX
套接字(参见 unix(7)
手册页)。这些很容易在 C++ 和 python 中创建(sockets
模块)。这样可以避免端口冲突或在本地系统上打开端口的权限问题。
Unix 套接字的性能相当不错,如果您决定与远程工作者一起工作,可以轻松地将其替换为 AF_INET6
套接字。
对于数据打包/解包,使用compiled Struct
objects 的struct
模块对我来说似乎是合理的。我过去就是这样做的,而且性能非常好(没有进行测量,因为它对我来说太好了,无法调查)。
【讨论】:
+1,虽然我不认为 stdin/stdout 管道对于 Python 客户端在启动后连接到的守护进程是可行的。 是的,我同意使用 Unix 域套接字有很多优点。我同意斯文的观点,我认为你关于管道的说法也没有道理。此外,您根本没有涉及在打开套接字后通过套接字传输数据的方法(我提到了打包的结构,使用struct
模块)
@python_noob 好吧,我没有读到 C 进程将始终在后台,并且不会被 Python 进程去后台运行。在那种情况下,管道是无稽之谈。 struct
对我来说很好,这就是为什么我没有明确提及它,我会在一分钟内更正它。【参考方案2】:
我的默认选择是使用通过 localhost 进行通信的普通套接字。套接字是一种很好理解的语言和平台中立的 API,性能往往非常好。它们还具有不将您绑定到同一个盒子上的两个进程的优势,这在许多情况下都是有利的。
【讨论】:
我知道这很常见,但我的经验是这会产生非常糟糕的结果。它会导致代码中的安全问题,这些问题不应该是网络可访问的,无论是意外让外界与您的程序交谈还是让不受信任的用户与它交谈。它还存在命名空间问题,因为您可能会选择与其他人相同的端口号。最后,使用端口号而不是健全的路径是很尴尬的。以上是关于在长时间运行的 c 进程和 python 之间进行双向 IPC 的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
以与长时间运行的 Python 进程不同的用户身份运行子进程
python multiprocessing.Pool kill *特定*长时间运行或挂起的进程
如何使用 python 烧瓶防止 230 秒 azure 网关超时以进行长时间运行的工作负载
使用 MaxDegreeOfParallism 进行并行 foreach,有时会在两者之间停止进程