多处理KeyboardInterrupt处理

时间:2015-12-26 16:18:20

标签: python multiprocessing

这个问题似乎一直困扰着我 - 所有解决方案都更像是变通方法,并为代码增加了相当多的复杂性。 由于任何有关此事的帖子都已经过了很长时间,以下是否有任何simple解决方案 - 在检测到键盘中断后,干净地退出所有孩子的程序,终止程序?

下面的代码是我的multiproccess结构的片段 - 我想保留尽可能多的东西,同时添加所需的功能:

from multiprocessing import Pool
import time

def multiprocess_init(l):
    global lock
    lock = l

def synchronous_print(i):
    with lock:
        print i
        time.sleep(1)

if __name__ == '__main__':

    lock = Lock()
    pool = Pool(processes=5, initializer=multiprocess_init, initargs=(lock, ))

    for i in range(1,20):
        pool.map_async(synchronous_print, [i])

    pool.close() #necessary to prevent zombies
    pool.join() #wait for all processes to finish

1 个答案:

答案 0 :(得分:1)

简短的回答是转向python 3. Python 2在线程/进程同步方面存在多个问题,这些问题已在python 3中得到修复。

在您的情况下,每次发送键盘中断时,multiprocessing都会顽固地重新创建您的子进程,pool.close将卡住并永不退出。您可以通过使用os.exit明确退出子流程并等待apply_async的单个结果来减少问题,这样您就不会陷入pool.close监狱。

from multiprocessing import Pool, Lock
import time
import os

def multiprocess_init(l):
    global lock
    lock = l
    print("initialized child")

def synchronous_print(i):
    try:
        with lock:
            print i
            time.sleep(1)
    except KeyboardInterrupt:
        print("exit child")
        os.exit(2)

if __name__ == '__main__':

    lock = Lock()
    pool = Pool(processes=5, initializer=multiprocess_init, initargs=(lock, ))

    results = []
    for i in range(1,20):
        results.append(pool.map_async(synchronous_print, [i]))

    for result in results:
        print('wait result')
        result.wait()

    pool.close() #necessary to prevent zombies
    pool.join() #wait for all processes to finish
    print("Join completes")