我有以下代码(仅测试关于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()
?
N.B。:我故意在这里使用流程而不是线程,所以如果解决方案考虑到这一点,我会很感激。
在阅读this question的答案之后,我尝试了一件事,但它遇到了同样的问题:
#!/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 + < kbd> 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)
,其中999999
的超时时间足以满足您的目的。