Python のマルチプロセッシング モジュールでは、Pool クラスは複数のプロセスにタスクを分散する便利な方法を提供します。ただし、次のコード スニペットで示されているように、プールでの KeyboardInterrupt イベントの処理は困難な場合があります。
<code class="python">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()</code>
このコードの実行時に Ctrl C を押してもクリーンアップ プロセスはトリガーされず、サブプロセスが無期限に実行されたままになります。この問題に対処するには、次の回避策を検討してください。
コード内で確認された動作は、Python のバグの結果です。 threading.Condition.wait() の条件を待機している場合、KeyboardInterrupt は送信されません。 Pool.map() は内部で条件待機を使用するため、割り込みは決して受信されません。
解決策は、タイムアウトを指定できる Pool.map_async() を使用することです。十分に長いタイムアウト (9999999 など) を設定することで、適切な時間内に割り込みが確実にトリガーされるようにすることができます。
したがって、
<code class="python"> results = pool.map(slowly_square, range(40))</code>
を
に置き換えます。<code class="python"> results = pool.map_async(slowly_square, range(40)).get(9999999)</code>
この回避策は、マルチプロセッシング プールで KeyboardInterrupt イベントを適切に処理する方法を提供し、ユーザーがプログラムをキャンセルしたときにすべてのサブプロセスを終了できるようにします。
以上がPython のマルチプロセッシング プールでキーボード割り込みを処理するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。