在Ubuntu 14.04上使用python3(3.4.3)我创建了一个Forker
类,我在两个不同的进程中使用它来创建子进程。这是Forker
类:
class Forker(object):
def __init__(self):
self.active_children = []
def reap_children(self):
while self.active_children:
pid,stat = os.waitpid(0, os.WNOHANG)
if not pid: break
self.active_children.remove(pid)
def fork(self, function, *args, **kwargs):
self.reap_children()
child_pid = os.fork()
if child_pid == 0:
function(*args, **kwargs)
os._exit(0)
else:
self.active_children.append(child_pid)
return child_pid
在我从这个类派生的两个不同的Linux进程中然后调用例如类似的东西:
self.fork(my_function, my_data)
然而,我仍然得到一些已经失效的python进程:
alexand+ 24777 24735 0 20:40 pts/29 00:00:00 [python3] <defunct>
alexand+ 24838 24733 0 20:40 pts/29 00:00:00 [python3] <defunct>
也许我可以改变一些东西来避免这些已经失效的过程?
答案 0 :(得分:4)
标记为<defunct>
的流程称为僵尸流程。系统将它们保持在已经不存在的状态,以允许其父级在完成运行后读取其状态。
有两种方法可以删除它们:
signal(SIGCHLD, SIG_IGN);
),则会立即删除子节点(没有失效状态),但是父节点没有其他方法可以等待它们。答案 1 :(得分:1)
离开的孩子是<defunct>
,直到父母等待他们。
由于您仅在reap_children()
新孩子时才在fork()
中呼叫等待,所以已退出的孩子将保持<defunct>
,直到下一个孩子分叉为止。要提前摆脱它们,您可以在较早时间调用reap_children()
(即等待)。通常,这是通过SIGCHLD信号的处理程序完成的。