"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > كيفية تنفيذ التسجيل المدرك للمعالجة المتعددة في بايثون: حل قائم على قائمة الانتظار؟

كيفية تنفيذ التسجيل المدرك للمعالجة المتعددة في بايثون: حل قائم على قائمة الانتظار؟

تم النشر بتاريخ 2024-11-03
تصفح:442

  How to Implement Multiprocessing-Aware Logging in Python: A Queue-Based Solution?

كيفية تنفيذ التسجيل المدرك للمعالجة المتعددة في بايثون

تسمح المعالجة المتعددة في بايثون بإنشاء عمليات متعددة تعمل بشكل مستقل. ومع ذلك، فإن الوصول إلى الموارد المشتركة مثل ملفات السجل يمكن أن يصبح معقدًا حيث قد تحاول عمليات متعددة الكتابة إليها في وقت واحد.

لتجنب هذه المشكلة، توفر وحدة المعالجة المتعددة في Python إمكانات تسجيل مدركة للمعالجة المتعددة على مستوى الوحدة. يتيح ذلك للمسجل منع تشويه رسائل السجل من خلال التأكد من أن عملية واحدة فقط تكتب إلى واصف ملف محدد في المرة الواحدة.

ومع ذلك، قد لا تكون الوحدات النمطية الموجودة داخل الإطار على علم بالمعالجة المتعددة، مما يؤدي إلى الحاجة إلى للحلول البديلة. تتضمن إحدى الطرق إنشاء معالج سجل مخصص يرسل رسائل التسجيل إلى العملية الرئيسية عبر أنبوب.

يتم توفير تنفيذ هذا الأسلوب أدناه:

from logging.handlers import RotatingFileHandler
import multiprocessing, threading, logging, sys, traceback

class MultiProcessingLog(logging.Handler):
    def __init__(self, name, mode, maxsize, rotate):
        logging.Handler.__init__(self)

        # Set up the file handler for the parent process
        self._handler = RotatingFileHandler(name, mode, maxsize, rotate)
        
        # Create a queue to receive log messages from child processes
        self.queue = multiprocessing.Queue(-1)
        
        # Start a thread in the parent process to receive and log messages
        t = threading.Thread(target=self.receive)
        t.daemon = True
        t.start()

    def receive(self):
        while True:
            try:
                # Get a log record from the queue
                record = self.queue.get()
                
                # Log the record using the parent process's file handler
                self._handler.emit(record)
            # Exit the thread if an exception is raised
            except (KeyboardInterrupt, SystemExit):
                raise
            except EOFError:
                break
            except:
                traceback.print_exc(file=sys.stderr)

    def send(self, s):
        # Put the log record into the queue for the receiving thread
        self.queue.put_nowait(s)

    def _format_record(self, record):
        # Stringify any objects in the record to ensure that they can be sent over the pipe
        if record.args:
            record.msg = record.msg % record.args
            record.args = None
        if record.exc_info:
            dummy = self.format(record)
            record.exc_info = None
            
        return record

    def emit(self, record):
        try:
            # Format and send the log record through the pipe
            s = self._format_record(record)
            self.send(s)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)

    def close(self):
        # Close the file handler and the handler itself
        self._handler.close()
        logging.Handler.close(self)

يسمح معالج السجل المخصص هذا للوحدات النمطية داخل إطار العمل باستخدام ممارسات التسجيل القياسية دون الحاجة إلى أن تكون على دراية بالمعالجة المتعددة. يتم إرسال رسائل السجل من العمليات الفرعية إلى العملية الأصلية عبر أنبوب، مما يضمن عدم تشويهها وكتابتها بشكل صحيح في ملف السجل.

أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3