عملية Python لن تتصل بـ atexit
-
23-09-2019 - |
سؤال
أحاول استخدام 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:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started DEBUG:root:Main process terminated
أتوقع أن W.run.log_terminate()
سيتم استدعاؤه متى a.terminate()
و b.terminate()
يتم استدعاؤها ، والإخراج ليكون شيء مثل Likeso (التأكيد مضاف)!:
DEBUG:root:Main process started DEBUG:root:W-1 Started DEBUG:root:W-2 Started تصحيح: الجذر: W-1 إنهاء! تصحيح: الجذر: W-2 إنهاء! DEBUG:root:Main process terminated
لماذا لا يعمل هذا ، وهل هناك طريقة أفضل لتسجيل رسالة (من Process
السياق) عندما أ Process
يتم إنهاء؟
شكرا لك على مدخلاتك - إنه موضع تقدير كبير.
المحلول
تعديل: بناءً على الحل الذي اقترحه أليكس مارتيلي ، الأعمال التالية كما هو متوقع:
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
توثيق:
ملاحظة: لا يتم استدعاء الوظائف المسجلة عبر هذه الوحدة عندما يتم قتل البرنامج بإشارة ، أو عند اكتشاف خطأ داخلي فادح ، أو عند استدعاء OS._exit ().
المحلول
مثل المستندات قل،
في UNIX يتم ذلك باستخدام إشارة sigterm ؛ على Windows TerminateProcess () يستخدم. لاحظ أن معالجات الخروج والبنود أخيرًا ، وما إلى ذلك ، لن يتم تنفيذها.
إذا كنت في Unix ، فيجب أن تكون قادرًا على التقاطع SIGTERM
مع الإشارة, وأداء أي "أنشطة الإنهاء" التي تحتاجها ؛ ومع ذلك ، لا أعرف محلول منصة.