Pythonのマルチプロセッシングプールでのキーボード割り込み 質問する

Pythonのマルチプロセッシングプールでのキーボード割り込み 質問する

Python のマルチプロセッシング プールで KeyboardInterrupt イベントを処理するにはどうすればよいですか? 以下に簡単な例を示します。

from multiprocessing import Pool
from time import sleep
from sys import exit

def slowly_square(i):
    sleep(1)
    return i*i

def go():
    pool = Pool(8)
    try:
        results = pool.map(slowly_square, range(40))
    except KeyboardInterrupt:
        # **** THIS PART NEVER EXECUTES. ****
        pool.terminate()
        print "You cancelled the program!"
        sys.exit(1)
    print "\nFinally, here are the results: ", results

if __name__ == "__main__":
    go()

上記のコードを実行すると、 をKeyboardInterrupt押すと が発生します^Cが、その時点でプロセスがハングアップしてしまうため、外部から強制終了する必要があります。

^Cいつでも押すことができ、すべてのプロセスが正常に終了するようにしたいです。

ベストアンサー1

これは Python のバグです。threading.Condition.wait() で条件を待機しているときに、KeyboardInterrupt は送信されません。再現方法:

import threading
cond = threading.Condition(threading.Lock())
cond.acquire()
cond.wait(None)
print "done"

KeyboardInterrupt 例外は wait() が返されるまで配信されず、返されることもないため、割り込みは発生しません。KeyboardInterrupt は、ほぼ確実に条件待機を中断します。

タイムアウトが指定されている場合は、これは発生しないことに注意してください。cond.wait(1) はすぐに割り込みを受け取ります。したがって、回避策はタイムアウトを指定することです。これを行うには、

    results = pool.map(slowly_square, range(40))

    results = pool.map_async(slowly_square, range(40)).get(9999999)

または類似。

おすすめ記事