异常或KeyboardInterrupt时从多处理池退出?

时间:2015-06-11 16:52:57

标签: python multiprocessing python-multiprocessing

我希望我的程序在按 Ctrl + C 后退出:

public static int digitsStripTrailingZero(BigDecimal value)
{
    return digits(value.stripTrailingZeros());
}

public static int digits(BigDecimal value)
{
    return Math.max(0, value.scale());
}

此代码无法正常工作:按 Ctrl + C 时,程序不会退出。相反,它每次打印一些import multiprocessing import os import time def sqr(a): time.sleep(0.2) print 'local {}'.format(os.getpid()) #raise Exception() return a * a pool = multiprocessing.Pool(processes=4) try: r = [pool.apply_async(sqr, (x,)) for x in range(100)] pool.close() pool.join() except: print 121312313 pool.terminate() pool.join() print 'main {}'.format(os.getpid()) ,并且永远陷入困境。

另外,如果我在KeyboardInterrupt中取消注释#raise ...,我希望尽快退出。 Exception thrown in multiprocessing Pool not detected中的解决方案似乎没有帮助。

更新

我想我终于得到了这个:(让我知道是不是错了)

sqr

1 个答案:

答案 0 :(得分:3)

这是因为Python 2.x错误导致对pool.join()的调用不可中断。它在Python 3.x中运行良好。通常,解决方法是将非常大的timeout传递给join,但multiprocessing.Pool.join不会使用timeout参数,因此您根本无法使用它。相反,您需要等待池中的每个单独任务完成,并将timeout传递给wait()方法:

import multiprocessing
import time
import os

Pool = multiprocessing.Pool

def sqr(a):
    time.sleep(0.2)
    print('local {}'.format(os.getpid()))
    #raise Exception()
    return a * a

pool = Pool(processes=4)

try:
    r = [pool.apply_async(sqr, (x,)) for x in range(100)]
    pool.close()
    for item in r:
        item.wait(timeout=9999999) # Without a timeout, you can't interrupt this.
except KeyboardInterrupt:
    pool.terminate()
finally:
    pool.join()

print('main {}'.format(os.getpid()))

这可以在Python 2和3上中断。