我有以下代码(只是测试有关 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 999999
is a timeout 大到足以满足您的目的。