我遇到了一个问题,子进程调用(应该几乎立即返回)最终会被阻塞(实际的子进程已经失效,并且没有被清理)。这似乎只在我同时使用线程时才会发生。下面的节目很好地再现了我所看到的。通过运行它,您会看到主机名被打印了很多次,数字在范围内循环,直到它被阻止。我怀疑一旦一个线程完成,失效的进程就会被清除,然后它还会再次发生。
有人知道发生了什么,以及我如何在不发生这种情况的情况下使用线程和子流程吗?我在Ubuntu 11.4上使用Python 2.7.1+。
import os
import subprocess
import threading
class DummyThread(threading.Thread):
def run(self):
proc = subprocess.Popen(['sleep', '100'])
proc.wait()
while True:
dummy = DummyThread()
dummy.start()
for i in range(10):
print i
subprocess.check_call(['hostname'])
运行此操作会导致子进程失效并阻塞主线程:
user 28665 10543 1 22:55 pts/2 python blocker.py
user 28667 28665 0 22:55 pts/2 sleep 100
user 28679 28665 0 22:55 pts/2 sleep 100
user 28691 28665 0 22:55 pts/2 sleep 100
user 28703 28665 0 22:55 pts/2 sleep 100
user 28715 28665 0 22:55 pts/2 sleep 100
user 28727 28665 0 22:55 pts/2 sleep 100
user 28739 28665 0 22:55 pts/2 sleep 100
user 28751 28665 0 22:55 pts/2 sleep 100
user 28763 28665 0 22:55 pts/2 sleep 100
user 28775 28665 0 22:55 pts/2 sleep 100
user 28787 28665 0 22:55 pts/2 sleep 100
user 28799 28665 0 22:55 pts/2 sleep 100
user 28800 28665 0 22:55 pts/2 [hostname] <defunct>
我在ubuntu 12.04(python 2.7.3)和OS X 10.8(python 2.7.2)上重现了这个问题。
如果在对子流程的调用中设置close_fds=True,问题就会消失。Popen和subprocess.check_call.
我不确定这意味着什么,但它可能会帮助有更多知识的人完全回答这个问题。