我在Python中工作,我想找到一个工作流来支持两个进程(main process和sub-process)相互通信。我指的是主进程向子进程发送一些数据的能力(也许,通过写入子进程的stdin),以及子进程向主进程发送一些数据的能力。这也意味着两者都可以读取发送给他们的数据(我正在考虑从stdin读取)。在
我试图使用子进程库,但它似乎旨在处理那些只提供一次输出然后终止的进程,而我希望动态交换数据并仅在收到这样的命令时关闭子进程。在
我在这里读了很多关于StackOverflow解决与我的问题密切相关的答案,但是没有一个我觉得满意,因为这些问题的答案在一个重要的细节上与我的不同:我需要我的主流程能够与其子流程动态地交换数据,而不仅仅是一次,这又意味着子进程应该一直运行,直到它从主进程接收到终止的某个命令为止。在
我对使用第三方库持开放态度,但如果您提出一个完全基于python标准库的解决方案,效果会更好。在
对于您的用例来说,管道似乎是一个合适的选择。注意,在正常情况下,读写端都期望数据被写入或消耗。还要确保缓冲区不会让您感到意外(没有任何东西通过,因为除非相应地设置,否则缓冲区不会自动刷新,除非在预期的边界上)。在
两个管道(它们是单向的)如何在两个进程之间使用的一个基本示例:
实际上,使用
subprocess
会更容易、更实用,而且您可能希望exec
另一个二进制文件。前者需要被告知不要关闭(至少是相关的管道)文件描述符,后者需要管道文件描述符是可继承的(没有设置O_CLOEXEC
标志)。否则同上。在子代码:
^{pr2}$父脚本:
想想看,我忘了问,孩子是需要stdin/out来做什么,还是可以用它来获取信息。那就更简单了:
儿童:
家长:
如前所述,它并不是真正针对python的,这些只是关于如何使用管道作为一个选项的粗略提示。在
您希望使用
subprocess.PIPE
创建一个Popen
对象作为标准输入和输出,并使用其file对象进行通信,而不是使用一个像run
(以及更老、更具体的像check_output
)的控制柄进行通信。挑战在于避免死锁:在这样一种情况下很容易着陆:每个进程都在试图写,管道缓冲区被填满(因为没有人从它们中读取数据),所有的东西都挂起。您还必须记住在这两个进程中flush
,以避免请求或响应卡在file
对象的缓冲区中。在提供
Popen.communicate
是为了避免这些问题,但它只支持单个字符串(而不是正在进行的会话)。传统的解决方案是select
,但它也可以使用单独的线程来发送请求和读取结果。(这是使用CPython线程而不使用GIL的原因之一:每个线程都是为了运行而另一个线程被阻塞,所以很少有争用。)当然,同步是一个问题,您可能需要做一些工作,使多线程客户机在外部像一个简单的同步函数调用一样工作。在注意两个进程都需要
flush
,但是如果其中一个实现这样的非阻塞I/O就足够了;一个进程通常在启动另一个进程的进程中执行该任务,因为这是已知的必要的(而这类程序是例外)。在相关问题 更多 >
编程相关推荐