【发布时间】:2016-11-10 09:27:44
【问题描述】:
我遇到了一个问题,即使在调用 proc.terminate() 之后,对 proc.communicate() 的调用仍然挂起。
我通过调用创建要在后台运行的任务
import subprocess as sub
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, shell=False)
脚本完成后,我会调用terminate()、communicate() 和wait() 来从进程中收集信息。
p.terminate()
errorcode = p.wait()
(pout, perr) = p.communicate()
脚本在调用通信时挂起。我假设在终止调用之后的任何通信调用都会立即返回。有什么理由会失败吗?
编辑:我使用这种方法是因为该命令实际上是一个不会自行终止的紧密循环。我想使用 p.terminate() 来做到这一点,然后看看 stdout 和 stderr 必须提供什么。
【问题讨论】:
-
当然,你刚刚终止了它,你为什么不直接调用communicate?
-
如果
p.wait()返回但p.communicate()“挂起”,那么它可能与Python subprocess .check_call vs .check_output有关(check_call()在内部调用.wait(),check_output()在内部调用.communicate())。不相关:无需显式调用p.wait():无论如何都会在内部调用p.wait(),因此您可以在p.communicate()返回后使用p.returncode。一般来说,在p.communicate()之前调用p.wait()是一种不好的做法,它可能会使活动进程死锁(在这种情况下不适用——进程已死)。 -
@PadraicCunningham:这不是那么简单,例如,如果子进程在您明确终止它之前不退出怎么办。另一种情况:如果子进程可能产生自己的子进程,那么
p.communicate()可能会延迟;阅读我对the linked question的回答。 -
@J.F.Sebastian,是的,有效点数,这就是为什么我问你为什么不直接调用通信? 如,有什么具体原因。
-
在“命令”中调用的进程不会产生任何子进程,而是在一个紧密的循环中旋转,直到它被其他东西终止。我不能只调用communicate(),因为它会等待程序自行终止,而它永远不会这样做。
标签: python subprocess