我尝试了pyxpect和subprocess.Popen从python调用外部长期后台进程(此进程使用套接字与外部应用程序通信),具有以下详细信息。
subprocess.Popen(launchcmd,stdin = subprocess.PIPE,stdout = subprocess.PIPE,stderr = subprocess.PIPE) 这很好用。我不需要做任何其他事情。但是,因为我必须立即获得输出,所以我选择pexpect来避免管道文件缓冲区问题。
obj = pexpect.spawn(launchcmd,timeout = None) 启动外部进程后,我使用一个单独的线程来执行“readline”来读取已启动进程“obj”的输出,一切正常。
obj = pexpect.spawn(launchcmd,timeout = None) 在启动外部流程之后,我什么也没做,就是把它留在那里。虽然,通过使用“ps -e”命令,我可以找到启动的进程,但启动的进程似乎被阻止,无法在套接字中与其他应用程序通信。
行。更具体地说,我提出了一些示例代码来表达我的问题。
import subprocess
import pexpect
import os
t=1
while(True):
if(t==1):
background_process="./XXX.out"
launchcmd = [background_process]
#---option 3--------
p=pexpect.spawn(launchcmd, timeout=None) # process launced, problem with socket.
#---option 1--------
p=subprocess.Popen(launchcmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # process launced, everything fine
t=0
有人能告诉我第三种选择有什么问题吗?如果是因为我没有使用单独的线程来操作输出,为什么第一个选项适用于subprocess.popen?我怀疑pexpect使用套接字启动进程有问题,但我不确定,特别是考虑到选项2运行良好。
答案 0 :(得分:1)
我认为你这太复杂了。
是的,最好使用pty
代替pipe
与后台进程通信,因为大多数应用程序都会识别tty / pty设备并切换到使用无缓冲输出,(或者最少行缓冲)。
但为什么要观察呢?只需使用Python的pty模块。首先调用openpty
来获取一些文件句柄,然后使用Popen
来生成进程。示例代码可在以下问题中找到(带绿色复选标记的答案)Python Run a daemon sub-process & read stdout