这很容易。
创建一个输出大量文本的进程don't读取输出:
p = subprocess.Popen(["ls","-R"],stdout=subprocess.PIPE)
p.wait()
一段时间后,标准输出管道已满,进程被阻塞。
这是一种死锁情况,因为子进程在消耗之前无法再向输出写入内容(即:从不),并且 python 进程等待子进程完成。
为了避免死锁,您可以使用读取行循环:
p = subprocess.Popen(["ls","-R"],stdout=subprocess.PIPE)
for line in p.stdout:
# do something with the line
p.wait()
communicate
也修复了这个问题,但也修复了两个输出的更棘手的情况and错误流被重定向到单独的流(在这种情况下,上面的简单循环仍然可能死锁)。
假设你有一个编译过程
p = subprocess.Popen(["gcc","-c"]+mega_list_of_files,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
现在你想获得这个的输出,所以你这样做:
output = p.stdout.read()
不幸的是,当您读取输出流时,会弹出很多错误,从而阻塞错误流:再次死锁。
尝试读取错误流,可能会发生完全相反的情况:大量标准输出输出阻塞您的进程。
communicate
使用多线程能够同时处理输出和错误流并将它们分开,没有阻塞的风险。唯一需要注意的是,您无法实时控制逐行处理输出/打印程序输出:
p = subprocess.Popen(["gcc","-c"]+mega_list_of_files,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
output,error = p.communicate()
return_code = p.wait()