我有以下三个脚本,当我运行main.py文件时,它会生成child.py,再次执行subchild.py并迅速终止,subchild.py却保持执行了很多时间。
问题在于,main.py在p.communicate()处被阻止,直到subchild.py终止。如果我打开任务管理器并杀死正在运行的subchild.py main.py,则立即返回child.py的输出
所以我的问题如下
# main.py file
if __name__ == '__main__':
import subprocess
p = subprocess.Popen(
["python", "child.py"],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE
)
out, _ = p.communicate()
print(out)
# child.py file
if __name__ == '__main__':
import subprocess
print("Child running")
p = subprocess.Popen(["python", "subchild.py"])
print("Child pid - ", p.pid)
exit(1)
# subchild.py file
if __name__ == '__main__':
import time
time.sleep(10000)
注意:我正在Windows 7 Enterprise上尝试此操作。我正在使用python3.6.6
评论后更新:
在main.py上,我需要child.py的pid,stdout,stderr和进程对象,以便以后可以在任何时候从main.py中杀死child.py。这段代码只是我正在构建的一些API的一部分,用户希望控件在需要时终止该进程。 subprocesses.call或subprocesses.run不允许我控制process
对象。我也将无法控制要作为main.py的输入接收的child.py命令,因此,我需要以某种方式不要等待subchild.py并在完成后立即退出child.py的输出。 / p>
答案 0 :(得分:2)
您的communicate
通话不仅要等待孩子完成。它首先尝试读取孩子的stdout和stderr的全部内容。
即使孩子已经完成,父母也不会停止阅读,因为孙子继承了孩子的stdin,stdout和stderr 。父母必须等待孙子完成,或者至少要等待孙子关闭其stdout和stderr,然后父母才能确定已完成阅读。
答案 1 :(得分:1)
现在,child.py将始终等待subchild.py完成。如果您不需要等待,可以在child.py代码中尝试使用subprocess.call()
作为替代。将Popen()
逻辑替换为call()
逻辑。
p = subprocess.call(["python", "subchild.py"])
这里是参考:https://docs.python.org/2/library/subprocess.html#subprocess.call
另一种方法是保留代码,因为它实际上是对main.py文件中使用.call()
的更改。
import subprocess
p = subprocess.call(
["python", "child.py"],
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE
)
您提到您不能使用.call(),因为您需要将其杀死,但是事实并非如此。进行此更改将使您能够:
答案 2 :(得分:1)
最后,我自己找到了解决方案,这似乎是python的未解决问题。看到这个问题很高兴。 https://bugs.python.org/issue26731