سؤال

أحاول استخدام 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 مع الإشارة, وأداء أي "أنشطة الإنهاء" التي تحتاجها ؛ ومع ذلك ، لا أعرف محلول منصة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top