主进程产生子进程,子进程进入永久循环模式。当主进程要求子进程退出时,如何能安全地退出子进程呢?
参考一些代码,我写了这个例子。运行之后,用kill pid试试。pid是主进程的pid。当然子进程的也没问题。
1)如果kill pid为子进程的pid,当所有子进程都kill掉了,主进程就关闭了。这也是我们想要的结果。
2)如果kill pid为主进程的pid,主进程向子进程发送退出信号,然后等全部子进程关闭后退出。
保证了主进程在所有子进程退出之后退出。
#!/usr/bin/python2.7 #-*- coding: UTF-8 -*- # graceful_exit_event.py # UTF-8 without BOM # # refer: # http://stackoverflow.com/questions/26414704/how-does-a-python-process-exit-gracefully-after-receiving-sigterm-while-waiting?rq=1 # # init created: 2016-07-13 # last updated: 2016-07-13 # ####################################################################### import os, sys, signal, time, multiprocessing class GracefulExitException(Exception): pass def signal_handler(signum, frame): raise GracefulExitException() class GracefulExitEvent(object): def __init__(self, num_workers): self.exit_event = multiprocessing.Event() pass def is_stop(self): return self.exit_event.is_set() def notify_stop(self): self.exit_event.set() def worker_proc(gee): print "worker(%d) start ..." % os.getpid() try: while not gee.is_stop(): # do task job here print ".", time.sleep(1) else: print "" print "worker process(%d) got exit event." % os.getpid() print "worker process(%d) do cleanup..." % os.getpid() time.sleep(1) print "[%d] 3" % os.getpid() time.sleep(1) print "[%d] 2" % os.getpid() time.sleep(1) print "[%d] 1" % os.getpid() except GracefulExitException: print "worker(%d) got GracefulExitException" % os.getpid() finally: print "worker(%d) exit." % os.getpid() sys.exit(0) ####################################################################### if __name__ == "__main__": print "main process(%d) start" % os.getpid() # Use signal handler to throw exception which can be caught # by worker process to allow graceful exit. signal.signal(signal.SIGTERM, signal_handler) gee = GracefulExitEvent(1) # Start some workers process and run forever workers = [] for i in range(0, 10): wp = multiprocessing.Process(target=worker_proc, args=(gee,)) wp.start() workers.append(wp) try: for wp in workers: wp.join() except GracefulExitException: print "main process(%d) got GracefulExitException" % os.getpid() gee.notify_stop() for wp in workers: wp.join() pass # last message print "main process(%d) exit." % os.getpid() sys.exit(0)