2

我有以下代码(只是测试有关 Pool 类的一些假设):

#!/usr/bin/env python
from time import sleep
from multiprocessing import Pool

def run_process(args):
    print "Sleeping %d seconds" % (args * 2)
    sleep(args * 2)
    print "Slept %d seconds" % (args * 2)

def main():
    test = [1,2,3,1,2,3,1,2,3]
    pool = Pool()
    pool.map_async(run_process, test).get()

if __name__ == '__main__':
    main()

最终test将成为要传递给每个调用的参数列表,run_process以便它产生一个命令(即一个单独的进程)。

现在,当我按下Ctrl+C时,不幸的是它甚至没有拆除直接的子进程(从文档中听起来像是Pool创建了简单的子进程)。终端上发生的事情(Ubuntu 10.04,Python 2.6.5,如果这很重要)是^C每当我按下它时我都会看到回声,但是当所有孩子都应该退出“工作”时,父母也不会及时死亡(即睡眠)我也无法在不杀死父进程的情况下回收终端。

我如何调整我的脚本,以便它会拆除直接的孩子(以及后来产生的命令)?我想我正在尝试使用multiprocessing.Pool.close()multiprocessing.Pool.terminate()来自信号处理程序?!

注意:我故意在这里使用进程而不是线程,所以如果解决方案考虑到这一点,我将不胜感激。


这是我在阅读完这个问题的答案后尝试过的一件事,但它遇到了同样的问题:

#!/usr/bin/env python
from signal import signal
from time import sleep
from multiprocessing import Pool

def init_worker():
    import signal
    signal(signal.SIGINT, signal.SIG_IGN)

def run_process(args):
    print "Sleeping %d seconds" % (args * 2)
    sleep(args * 2)
    print "Slept %d seconds" % (args * 2)

def main():
    test = [1,2,3,1,2,3,1,2,3]
    try:
        pool = Pool()
        pool.map_async(run_process, test).get()
    except KeyboardInterrupt:
        pool.terminate()
        pool.wait()

if __name__ == '__main__':
    main()

添加一个非常大的超时(作业可以运行数周,因此超时必须足够大以覆盖它)Pool.get()似乎允许我使用Ctrl+ C,尽管输出有些令人困惑:

Traceback (most recent call last):
  File "./test.py", line 26, in <module>
    main()
  File "./test.py", line 23, in main
    pool.wait()
AttributeError: 'Pool' object has no attribute 'wait'

摆脱try/后except,回溯看起来“更自然”。因此,诀窍是将原始脚本的行更改为pool.map_async(run_process, test).get()类似于pool.map_async(run_process, test).get(999999)where 999999is a timeout 大到足以满足您的目的。

4

0 回答 0