多处理键盘中断处理

Multiprocessing KeyboardInterrupt handling

这个问题似乎一直困扰着我——所有的解决方案都更像是变通方法,并且给代码增加了相当多的复杂性。 自从发布了与此相关的任何帖子以来已经有一段时间了,是否有任何 simple 解决以下问题的方法 - 在检测到键盘中断时,干净地退出所有子进程,终止程序?

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

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

简短的回答是移至 python 3。Python 2 有多个 thread/process 同步问题已在 python 3.[=16 中修复=]

在您的情况下,每次您发送键盘中断时,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")