Bri*_*unt 20 python children daemon multiprocessing zombie-process
使用python-daemon时,我正在创建子进程likeo:
import multiprocessing
class Worker(multiprocessing.Process):
def __init__(self, queue):
self.queue = queue # we wait for things from this in Worker.run()
...
q = multiprocessing.Queue()
with daemon.DaemonContext():
for i in xrange(3):
Worker(q)
while True: # let the Workers do their thing
q.put(_something_we_wait_for())
Run Code Online (Sandbox Code Playgroud)
当我用Ctrl-C或SIGTERM等杀死父守护进程(即不是Worker)时,孩子们不会死.怎么杀了孩子?
我的第一个想法是使用atexit杀死所有的工人,喜欢:
with daemon.DaemonContext():
workers = list()
for i in xrange(3):
workers.append(Worker(q))
@atexit.register
def kill_the_children():
for w in workers:
w.terminate()
while True: # let the Workers do their thing
q.put(_something_we_wait_for())
Run Code Online (Sandbox Code Playgroud)
但是,守护进程的孩子们处理起来很棘手,我不得不考虑如何做到这一点并提出意见.
谢谢.
Dan*_*l G 31
你的选择有点受限.如果self.daemon = True
在Worker
类的构造函数中执行操作并不能解决您的问题,并且尝试在父级中捕获信号(即SIGTERM, SIGINT
)不起作用,则可能必须尝试相反的解决方案 - 而不是让父级杀死子级,您可以当父母去世时,让孩子们自杀.
第一步是给构造函数Worker
的PID
父进程的(你可以做到这一点用os.getpid()
).然后,不要只是self.queue.get()
在worker循环中执行,而是执行以下操作:
waiting = True
while waiting:
# see if Parent is at home
if os.getppid() != self.parentPID:
# woe is me! My Parent has died!
sys.exit() # or whatever you want to do to quit the Worker process
try:
# I picked the timeout randomly; use what works
data = self.queue.get(block=False, timeout=0.1)
waiting = False
except queue.Queue.Empty:
continue # try again
# now do stuff with data
Run Code Online (Sandbox Code Playgroud)
上面的解决方案检查父PID是否与它原来的不同(也就是说,如果子进程被采用init
或lauchd
因为父进程死亡) - 请参阅参考.但是,如果由于某种原因这不起作用,您可以使用以下函数替换它(从此处改编):
def parentIsAlive(self):
try:
# try to call Parent
os.kill(self.parentPID, 0)
except OSError:
# *beeep* oh no! The phone's disconnected!
return False
else:
# *ring* Hi mom!
return True
Run Code Online (Sandbox Code Playgroud)
现在,当父母去世(无论出于何种原因)时,童工将像苍蝇一样自发地堕落 - 就像你想要的那样,你守护着! :-D