避免与Python中的Popen和stdout = PIPE发生死锁

时间:2017-01-17 16:39:47

标签: python python-2.7 deadlock popen

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

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 的民意调查的文档可能会导致死锁。此外, communication()可用于解决此问题。我在这里使用了communication()。

我的代码是否也会因为沟通导致死锁,或者我使用沟通使用错误了吗?

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

1 个答案:

答案 0 :(得分:2)

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

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

带他们出去;这里没有必要。 communicate()将等待子进程关闭其FD(如退出时那样);当你自己添加一个循环,并且直到该循环完成后才读取,那么你的程序可能会被无限期地卡住,试图写出在communicate()导致之前无法写入的内容管道的另一边开始阅读。

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