在 python 中使用 Popen 和 stdout = PIPE 避免死锁

Avoid Deadlock wtih Popen and stdout = PIPE in python

我正在使用 Popen 执行 shell 脚本。我也在使用 stdout=PIPE 来捕获 output.The 代码是

pipe = Popen('acbd.sh', shell=True, stdout = PIPE)
while pipe.poll() is None:
        time.sleep(0.5)
text = pipe.communicate()[0]
if pipe.returncode == 0:
    print "File executed"

根据文档,使用带有 stdout = PIPE 的轮询会导致死锁。也可以用communicate()来解决这个问题。我在这里使用了 communicate()。

我的代码是否也会导致通信死锁,或者我使用的通信用法有误?

此外,我在 subprocess.check_output 中有一个替代方案,但我更愿意使用 Popen 并使用相同的方式记录输出。

是的,你可以死锁,因为这两行:

while pipe.poll() is None:
    time.sleep(0.5)

把它们拿出来;这里不需要他们。 communicate() 将等待子进程按原样关闭其 FD(就像退出时发生的那样);当您自己添加一个循环时,并且在该循环完成后才读取,那么您的程序可能会无限期地卡住,试图写入直到 communicate() 才能写入的内容] 导致管道的另一端开始读取。


作为背景:write() 调用的 POSIX 规范不保证在阻塞之前可以写入 FIFO 的数据量,或者这个数据量数据将是一致的即使在给定系统中——因此,安全的事情是假设对 FIFO 的任何写入都是总是允许阻塞除非有 reader 积极使用该数据。