在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