在使用python的時候,為了提高效率,也為了避開python的GIL限制充分發揮多核的優勢,經常會使用multiprocessing模組來實現多進程處理。效率會有很大的提升,但這樣一來就引入的多進程管理的問題,比如:假定父進程設定的是啟動5個子進程,但在實際運行中因為種種原因有3個子進程異常退出,此時該怎麼辦?運行過程中想退出整個程式的運行,怎麼退出更合理,更優雅?
下面的python代碼簡單展示了如何使用signal來處理multiprocessing協作。
# -*- coding: utf-8 -*-'''Created on 2012-10-14 19:50@summary: multiprocessing coordinate demo@author: JerryKwan'''from multiprocessing import Event, Processimport signalimport timeSUBPROCESSES = []WORKERS = []EXIT = Event()def exit_handler(signum, frame): print "signal handler called with signal ", signum, " ", WORKERS, " ", frame EXIT.set() time.sleep(1) for w in WORKERS: print "begin to invoke stop_main_loop" w.stop_main_loop()signal.signal(signal.SIGTERM, exit_handler)signal.signal(signal.SIGINT, exit_handler)class Worker(object): """docstring for Worker""" def __init__(self, arg = "default arg"): super(Worker, self).__init__() self.arg = arg self.be_exit = Event() self.be_exit.clear() def stop_main_loop(self): print "stop_main_loop invoked" self.be_exit.set() def main_loop(self): print "main_loop invoked" while not self.be_exit.is_set(): print "do something" try: time.sleep(1) except Exception, e: print "exception occured, ", e print "exit from main_loop"def do_work(worker): print "do_work invoked" worker.main_loop()def create_subprocess(): ''' @summary: create subprocess @return: (worker, process) ''' w = Worker() p = Process(target = do_work, args = (w,)) p.daemon = True return (w, p)def main(): process_num = 2 for i in xrange(process_num): w, p = create_subprocess() WORKERS.append(w) SUBPROCESSES.append(p) # signal.signal(signal.SIGTERM, exit_handler) # signal.signal(signal.SIGINT, exit_handler) # start for p in SUBPROCESSES: p.start() # for p in SUBPROCESSES: # p.join() print "monitor subprocess" while not EXIT.is_set(): for i in xrange(len(SUBPROCESSES)): p = SUBPROCESSES[i] if not p.is_alive(): # create new process to replace the dead one print "%d process is dead, so i will create a new one to relace it." %i w, p = create_subprocess() WORKERS[i] = w SUBPROCESSES[i] = p p.start() time.sleep(1) print "main process exit" # wait subprocess exit # for i in xrange(process_num): # whileif __name__ == '__main__': main()