在 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 积极使用该数据。
我正在使用 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 积极使用该数据。