键盘中断与python的多处理池 [英] Keyboard Interrupts with python's multiprocessing Pool

查看:57
本文介绍了键盘中断与python的多处理池的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用python的多处理池处理KeyboardInterrupt事件?这是一个简单的示例:

How can I handle KeyboardInterrupt events with python's multiprocessing Pools? Here is a simple example:

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()

运行上面的代码时,按^C键会升高KeyboardInterrupt,但是该过程只是在此时挂起,我必须在外部将其杀死.

When running the code above, the KeyboardInterrupt gets raised when I press ^C, but the process simply hangs at that point and I have to kill it externally.

我希望能够随时按^C并使所有进程正常退出.

I want to be able to press ^C at any time and cause all of the processes to exit gracefully.

推荐答案

这是一个Python错误.等待threading.Condition.wait()中的条件时,从不发送KeyboardInterrupt.复制:

This is a Python bug. When waiting for a condition in threading.Condition.wait(), KeyboardInterrupt is never sent. Repro:

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

KeyboardInterrupt异常要等到wait()返回,并且永远不会返回之后,才会传递,因此中断永远不会发生. KeyboardInterrupt几乎可以肯定会中断条件等待.

The KeyboardInterrupt exception won't be delivered until wait() returns, and it never returns, so the interrupt never happens. KeyboardInterrupt should almost certainly interrupt a condition wait.

请注意,如果指定了超时,则不会发生这种情况; cond.wait(1)将立即收到中断.因此,一种解决方法是指定超时.为此,请替换

Note that this doesn't happen if a timeout is specified; cond.wait(1) will receive the interrupt immediately. So, a workaround is to specify a timeout. To do that, replace

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

使用

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

或类似的

这篇关于键盘中断与python的多处理池的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆