で使用しようとしていますatexit
がProcess
、残念ながら機能していないようです。コード例を次に示します。
import time
import atexit
import logging
import multiprocessing
logging.basicConfig(level=logging.DEBUG)
class W(multiprocessing.Process):
def run(self):
logging.debug("%s Started" % self.name)
@atexit.register
def log_terminate():
# ever called?
logging.debug("%s Terminated!" % self.name)
while True:
time.sleep(10)
@atexit.register
def log_exit():
logging.debug("Main process terminated")
logging.debug("Main process started")
a = W()
b = W()
a.start()
b.start()
time.sleep(1)
a.terminate()
b.terminate()
このコードの出力は次のとおりです。
DEBUG:root:メイン プロセスが開始されました DEBUG:root:W-1 開始 DEBUG:root:W-2 開始 DEBUG:root:メイン プロセスが終了しました
W.run.log_terminate()
とが呼び出されたときa.terminate()
にが呼び出され、出力が次のようになることを期待しb.terminate()
ます (強調を追加)!:
DEBUG:root:メイン プロセスが開始されました DEBUG:root:W-1 開始 DEBUG:root:W-2 開始 DEBUG:root:W-1 終了しました! DEBUG:root:W-2 終了しました! DEBUG:root:メイン プロセスが終了しました
なぜこれが機能しないのですか? また、 aが終了Process
したときに (コンテキストから)メッセージをログに記録するより良い方法はありますか?Process
ご意見をお寄せいただきありがとうございます。
解決
編集: Alex Martelli によって提案された解決策に基づいて、次は期待どおりに機能します。
import sys
import time
import atexit
import signal
import logging
import multiprocessing
logging.basicConfig(level=logging.DEBUG)
class W(multiprocessing.Process):
def run(self):
logging.debug("%s Started" % self.name)
def log_terminate(num, frame):
logging.debug("%s Terminated" % self.name)
sys.exit()
signal.signal(signal.SIGTERM, log_terminate)
while True:
time.sleep(10)
@atexit.register
def log_exit():
logging.debug("Main process terminated")
logging.debug("Main process started")
a = W()
b = W()
a.start()
b.start()
time.sleep(1)
a.terminate()
b.terminate()
atexit
ドキュメントの次のコメントに注意してください。
注: このモジュールを介して登録された関数は、プログラムがシグナルによって強制終了されたとき、Python の致命的な内部エラーが検出されたとき、または os._exit() が呼び出されたときに呼び出されません。