在Python的多处理模块中,Pool类提供了一种在多个进程之间分配任务的便捷方法。然而,处理池中的 KeyboardInterrupt 事件可能具有挑战性,如代码片段所示:
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()
运行此代码时,按 Ctrl C 将不会触发清理过程,从而使子进程无限期地运行。要解决此问题,请考虑以下解决方法:
代码中观察到的行为是 Python bug 的结果。在 threading.Condition.wait() 中等待条件时,不会发送 KeyboardInterrupt。由于 Pool.map() 在内部使用条件等待,因此永远不会收到中断。
解决方案是使用 Pool.map_async(),它允许指定超时。通过设置足够长的超时时间(例如9999999),我们可以保证在合理的时间内触发中断。
因此,替换:
results = pool.map(slowly_square, range(40))
with:
results = pool.map_async(slowly_square, range(40)).get(9999999)
此解决方法提供了一种在多处理池中优雅地处理 KeyboardInterrupt 事件的方法,允许在用户取消程序时终止所有子进程。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3