Inhaltsverzeichnis
Hintergrund
So implementieren Sie
Verwenden Sie mehrere Prozesse, um das Hotloaden der Konfiguration zu implementieren
Verwenden Sie Signalsemaphore, um Hot Loading zu implementieren
采用multiprocessing.Event 来实现配置热加载
Heim Backend-Entwicklung Python-Tutorial So implementieren Sie das Hotloaden von Konfigurationsdateien in Python

So implementieren Sie das Hotloaden von Konfigurationsdateien in Python

May 07, 2023 pm 06:31 PM
python

    Hintergrund

    Aufgrund aktueller Arbeitsanforderungen ist es erforderlich, dem bestehenden Projekt eine neue Funktion hinzuzufügen, um die Konfigurations-Hot-Reloading-Funktion zu implementieren. Das sogenannte Hot-Reloading der Konfiguration bedeutet, dass wir, nachdem der Dienst die Konfigurationsaktualisierungsnachricht erhalten hat, die neueste Konfiguration verwenden können, um Aufgaben auszuführen, ohne den Dienst neu starten zu müssen.

    So implementieren Sie

    Im Folgenden verwende ich Multiprozess-, Multithread- und Coroutine-Methoden, um das Hotloaden der Konfiguration zu implementieren.

    Verwenden Sie mehrere Prozesse, um das Hotloaden der Konfiguration zu implementieren

    Wenn wir bei der Codeimplementierung mehrere Prozesse verwenden, aktualisiert der Hauptprozess 1 die Konfiguration und sendet Anweisungen, und der Aufgabenaufruf ist Prozess 2. Wie implementiert man das Hotloaden der Konfiguration?

    Verwenden Sie Signalsemaphore, um Hot Loading zu implementieren

    So implementieren Sie das Hotloaden von Konfigurationsdateien in Python

    Wenn der Hauptprozess die Konfigurationsaktualisierungsnachricht empfängt (wie empfängt der Konfigurationsleser die Konfigurationsaktualisierungsnachricht? Wir werden hier nicht darauf eingehen), fährt der Hauptprozess mit Unterprozess 1 fort sendet ein Kill-Signal. Nach dem Empfang des Kill-Signals startet die Signalverarbeitungsfunktion einen neuen Prozess und verwendet die neueste Konfigurationsdatei, um mit der Ausführung der Aufgabe fortzufahren.

    Hauptfunktion

    def main():
        # 启动一个进程执行任务
        p1 = Process(target=run, args=("p1",))
        p1.start()
    
        monitor(p1, run) # 注册信号
        processes["case100"] = p1 #将进程pid保存
        num = 0 
        while True: # 模拟获取配置更新
            print(
                f"{multiprocessing.active_children()=}, count={len(multiprocessing.active_children())}\n")
            print(f"{processes=}\n")
            sleep(2)
            if num == 4:
                kill_process(processes["case100"]) # kill 当前进程
            if num == 8:
                kill_process(processes["case100"]) # kill 当前进程
            if num == 12:
                kill_process(processes["case100"]) # kill 当前进程
            num += 1
    Nach dem Login kopieren

    signal_handler-Funktion

    def signal_handler(process: Process, func, signum, frame):
        # print(f"{signum=}")
        global counts
    
        if signum == 17:  # 17 is SIGCHILD 
            # 这个循环是为了忽略SIGTERM发出的信号,避免抢占了主进程发出的SIGCHILD
            for signame in [SIGTERM, SIGCHLD, SIGQUIT]:
                signal.signal(signame, SIG_DFL)
    
            print("Launch a new process")
            p = multiprocessing.Process(target=func, args=(f"p{counts}",))
            p.start()
            monitor(p, run)
            processes["case100"] = p
            counts += 1
    
        if signum == 2:
            if process.is_alive():
                print(f"Kill {process} process")
                process.terminate()
            signal.signal(SIGCHLD, SIG_IGN)
            sys.exit("kill parent process")
    Nach dem Login kopieren

    Der vollständige Code lautet wie folgt:

    #! /usr/local/bin/python3.8
    from multiprocessing import Process
    from typing import Dict
    import signal
    from signal import SIGCHLD, SIGTERM, SIGINT, SIGQUIT, SIG_DFL, SIG_IGN
    import multiprocessing
    from multiprocessing import Process
    from typing import Callable
    from data import processes
    import sys
    from functools import partial
    import time
    
    processes: Dict[str, Process] = {}
    counts = 2
    
    
    def run(process: Process):
        while True:
            print(f"{process} running...")
            time.sleep(1)
    
    
    def kill_process(process: Process):
        print(f"kill {process}")
        process.terminate()
    
    
    def monitor(process: Process, func: Callable):
        for signame in [SIGTERM, SIGCHLD, SIGINT, SIGQUIT]:
            # SIGTERM is kill signal.
            # No SIGCHILD is not trigger singnal_handler,
            # No SIGINT is not handler ctrl+c,
            # No SIGQUIT is RuntimeError: reentrant call inside <_io.BufferedWriter name=&#39;<stdout>&#39;>
            signal.signal(signame, partial(signal_handler, process, func))
    
    
    def signal_handler(process: Process, func, signum, frame):
        print(f"{signum=}")
        global counts
    
        if signum == 17:  # 17 is SIGTERM
            for signame in [SIGTERM, SIGCHLD, SIGQUIT]:
                signal.signal(signame, SIG_DFL)
            print("Launch a new process")
            p = multiprocessing.Process(target=func, args=(f"p{counts}",))
            p.start()
            monitor(p, run)
            processes["case100"] = p
            counts += 1
    
        if signum == 2:
            if process.is_alive():
                print(f"Kill {process} process")
                process.terminate()
            signal.signal(SIGCHLD, SIG_IGN)
            sys.exit("kill parent process")
    
    
    def main():
        p1 = Process(target=run, args=("p1",))
        p1.start()
        monitor(p1, run)
        processes["case100"] = p1
        num = 0
        while True:
            print(
                f"{multiprocessing.active_children()=}, count={len(multiprocessing.active_children())}\n")
            print(f"{processes=}\n")
            time.sleep(2)
            if num == 4:
                kill_process(processes["case100"])
            if num == 8:
                kill_process(processes["case100"])
            if num == 12:
                kill_process(processes["case100"])
            num += 1
    
    
    if __name__ == &#39;__main__&#39;:
        main()
    Nach dem Login kopieren

    Die Ausführungsergebnisse lauten wie folgt: Vorteile: Durch die Verwendung von Semaphoren kann die Kommunikation zwischen mehreren abgewickelt werden Prozessproblem.

    Nachteile: Der Code ist schwer zu schreiben und der geschriebene Code ist schwer zu verstehen. Sie müssen mit der Verwendung von Semaphoren vertraut sein, sonst ist es einfach, einen Fehler selbst zu schreiben (Alle Anfänger sollten ihn mit Vorsicht verwenden, außer erfahrene Fahrer.) Eine andere Sache, die nicht besonders verstanden wird, ist der -Prozess. Beenden()< /code> Das gesendete Signal ist <code>SIGTERM und die Zahl ist 15, aber das erste Mal, dass signal_handler das Signal empfängt, ist Zahl=17, wenn ich es verarbeiten möchte das Signal von 15, dann Dies führt zu dem Problem, dass der vorherige Prozess nicht abgebrochen werden kann. Wer sich mit Semaphoren auskennt, kann uns gerne einen Rat geben. Vielen Dank.

    Verwendung von multiprocessing.Event zum Implementieren des Konfigurations-Hotloadings

    Die Implementierungslogik besteht darin, dass der Hauptprozess 1 die Konfiguration aktualisiert und Anweisungen sendet. Prozess 2 startet die Planungsaufgabe.

    Zu diesem Zeitpunkt sendet der Hauptprozess 1, nachdem er die Konfiguration aktualisiert hat, eine Anweisung an Prozess 2. Die Anweisung zu diesem Zeitpunkt besteht darin, Event zu verwenden, um ein asynchrones Ereignis zu benachrichtigen. process.terminate() 发送出信号是SIGTERM number是15,但是第一次signal_handler收到信号却是number=17,如果我要去处理15的信号,就会导致前一个进程不能kill掉的问题。欢迎有对信号量比较熟悉的大佬,前来指点迷津,不甚感谢。

    采用multiprocessing.Event 来实现配置热加载

    实现逻辑是主进程1 更新配置并发送指令。进程2启动调度任务。

    这时候当主进程1更新好配置之后,发送指令给进程2,这时候的指令就是用Event一个异步事件通知。

    直接上代码

    scheduler 函数

    multiprocessing.active_children()=[<Process name=&#39;Process-1&#39; pid=2533 parent=2532 started>], count=1
    
    processes={&#39;case100&#39;: <Process name=&#39;Process-1&#39; pid=2533 parent=2532 started>}
    
    p1 running...
    p1 running...
    kill <Process name=&#39;Process-1&#39; pid=2533 parent=2532 started>
    multiprocessing.active_children()=[<Process name=&#39;Process-1&#39; pid=2533 parent=2532 started>], count=1
    
    processes={&#39;case100&#39;: <Process name=&#39;Process-1&#39; pid=2533 parent=2532 started>}
    
    signum=17
    Launch a new process
    p2 running...
    p2 running...
    multiprocessing.active_children()=[<Process name=&#39;Process-2&#39; pid=2577 parent=2532 started>], count=1
    
    processes={&#39;case100&#39;: <Process name=&#39;Process-2&#39; pid=2577 parent=2532 started>}
    
    p2 running...
    p2 running...
    multiprocessing.active_children()=[<Process name=&#39;Process-2&#39; pid=2577 parent=2532 started>], count=1
    
    processes={&#39;case100&#39;: <Process name=&#39;Process-2&#39; pid=2577 parent=2532 started>}
    
    p2 running...
    p2 running...
    multiprocessing.active_children()=[<Process name=&#39;Process-2&#39; pid=2577 parent=2532 started>], count=1
    
    processes={&#39;case100&#39;: <Process name=&#39;Process-2&#39; pid=2577 parent=2532 started>}
    
    p2 running...
    p2 running...
    kill <Process name=&#39;Process-2&#39; pid=2577 parent=2532 started>
    signum=17
    Launch a new process
    multiprocessing.active_children()=[<Process name=&#39;Process-2&#39; pid=2577 parent=2532 stopped exitcode=-SIGTERM>], count=1
    
    processes={&#39;case100&#39;: <Process name=&#39;Process-3&#39; pid=2675 parent=2532 started>}
    
    p3 running...
    p3 running...
    multiprocessing.active_children()=[<Process name=&#39;Process-3&#39; pid=2675 parent=2532 started>], count=1
    Nach dem Login kopieren

    event_scheduler 函数

    def scheduler():
        while True:
            print(&#39;wait message...&#39;)
            case_configurations = scheduler_notify_queue.get()
            print(f"Got case configurations {case_configurations=}...")
    
            task_schedule_event.set() # 设置set之后, is_set 为True
    
            print(f"Schedule will start ...")
            while task_schedule_event.is_set(): # is_set 为True的话,那么任务就会一直执行
                run(case_configurations)
    
            print("Clearing all scheduling job ...")
    Nach dem Login kopieren

    完整代码如下

    def event_scheduler(case_config):
    
        scheduler_notify_queue.put(case_config)
        print(f"Put cases config to the Queue ...")
    
        task_schedule_event.clear() # clear之后,is_set 为False
        print(f"Clear scheduler jobs ...")
    
        print(f"Schedule job ...")
    Nach dem Login kopieren

    执行结果如下

    import multiprocessing
    import time
    
    
    scheduler_notify_queue = multiprocessing.Queue()
    task_schedule_event = multiprocessing.Event()
    
    
    def run(case_configurations: str):
        print(f&#39;{case_configurations} running...&#39;)
        time.sleep(3)
    
    
    def scheduler():
        while True:
            print(&#39;wait message...&#39;)
            case_configurations = scheduler_notify_queue.get()
    
            print(f"Got case configurations {case_configurations=}...")
            task_schedule_event.set()
    
            print(f"Schedule will start ...")
            while task_schedule_event.is_set():
                run(case_configurations)
    
            print("Clearing all scheduling job ...")
    
    
    def event_scheduler(case_config: str):
    
        scheduler_notify_queue.put(case_config)
        print(f"Put cases config to the Queue ...")
    
        task_schedule_event.clear()
        print(f"Clear scheduler jobs ...")
    
        print(f"Schedule job ...")
    
    
    def main():
        scheduler_notify_queue.put(&#39;1&#39;)
        p = multiprocessing.Process(target=scheduler)
        p.start()
    
        count = 1
        print(f&#39;{count=}&#39;)
        while True:
            if count == 5:
                event_scheduler(&#39;100&#39;)
            if count == 10:
                event_scheduler(&#39;200&#39;)
            count += 1
            time.sleep(1)
    
    
    if __name__ == &#39;__main__&#39;:
        main()
    Nach dem Login kopieren

    总结

    使用Event事件通知,代码不易出错,代码编写少,易读。相比之前信号量的方法,推荐大家多使用这种方式。

    使用多线程或协程的方式,其实和上述实现方式一致。唯一区别就是调用了不同库中,queueevent

    Gehe direkt zum Code🎜🎜🎜Scheduler-Funktion🎜🎜
    wait message...
    Got case configurations case_configurations=&#39;1&#39;...
    Schedule will start ...
    1 running...
    1 running...
    Put cases config to the Queue ...
    Clear scheduler jobs ...
    Schedule job ...
    Clearing all scheduling job ...
    wait message...
    Got case configurations case_configurations=&#39;100&#39;...
    Schedule will start ...
    100 running...
    Put cases config to the Queue ...
    Clear scheduler jobs ...
    Schedule job ...
    Clearing all scheduling job ...
    wait message...
    Got case configurations case_configurations=&#39;200&#39;...
    Schedule will start ...
    200 running...
    200 running...
    Nach dem Login kopieren
    🎜🎜event_scheduler-Funktion🎜🎜
    # threading
    scheduler_notify_queue = queue.Queue()
    task_schedule_event = threading.Event()
    
    # async
    scheduler_notify_queue = asyncio.Queue()
    task_schedule_event = asyncio.Event()
    Nach dem Login kopieren
    🎜🎜Der vollständige Code lautet wie folgt🎜🎜rrreee🎜Die Ausführungsergebnisse lauten wie folgt🎜rrreee🎜 🎜Zusammenfassung🎜🎜 🎜Verwenden Sie das Ereignis Ereignisbenachrichtigung, der Code ist weniger fehleranfällig, der Code lässt sich weniger schreiben und ist leichter zu lesen. Im Vergleich zur vorherigen Semaphor-Methode wird empfohlen, diese Methode häufiger zu verwenden. 🎜🎜Die Verwendung von Multithreading oder Coroutine entspricht tatsächlich der oben genannten Implementierungsmethode. Der einzige Unterschied besteht darin, dass unterschiedliche Bibliotheken aufgerufen werden, queue und event.🎜rrreee

    Das obige ist der detaillierte Inhalt vonSo implementieren Sie das Hotloaden von Konfigurationsdateien in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

    Heiße KI -Werkzeuge

    Undresser.AI Undress

    Undresser.AI Undress

    KI-gestützte App zum Erstellen realistischer Aktfotos

    AI Clothes Remover

    AI Clothes Remover

    Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

    Undress AI Tool

    Undress AI Tool

    Ausziehbilder kostenlos

    Clothoff.io

    Clothoff.io

    KI-Kleiderentferner

    AI Hentai Generator

    AI Hentai Generator

    Erstellen Sie kostenlos Ai Hentai.

    Heiße Werkzeuge

    Notepad++7.3.1

    Notepad++7.3.1

    Einfach zu bedienender und kostenloser Code-Editor

    SublimeText3 chinesische Version

    SublimeText3 chinesische Version

    Chinesische Version, sehr einfach zu bedienen

    Senden Sie Studio 13.0.1

    Senden Sie Studio 13.0.1

    Leistungsstarke integrierte PHP-Entwicklungsumgebung

    Dreamweaver CS6

    Dreamweaver CS6

    Visuelle Webentwicklungstools

    SublimeText3 Mac-Version

    SublimeText3 Mac-Version

    Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

    Ist die Konversionsgeschwindigkeit beim Umwandeln von XML in PDF auf Mobiltelefon schnell? Ist die Konversionsgeschwindigkeit beim Umwandeln von XML in PDF auf Mobiltelefon schnell? Apr 02, 2025 pm 10:09 PM

    Die Geschwindigkeit der mobilen XML zu PDF hängt von den folgenden Faktoren ab: der Komplexität der XML -Struktur. Konvertierungsmethode für mobile Hardware-Konfiguration (Bibliothek, Algorithmus) -Codierungsoptimierungsmethoden (effiziente Bibliotheken, Optimierung von Algorithmen, Cache-Daten und Nutzung von Multi-Threading). Insgesamt gibt es keine absolute Antwort und es muss gemäß der spezifischen Situation optimiert werden.

    Wie konvertiere ich XML -Dateien in PDF auf Ihrem Telefon? Wie konvertiere ich XML -Dateien in PDF auf Ihrem Telefon? Apr 02, 2025 pm 10:12 PM

    Mit einer einzigen Anwendung ist es unmöglich, XML -zu -PDF -Konvertierung direkt auf Ihrem Telefon zu vervollständigen. Es ist erforderlich, Cloud -Dienste zu verwenden, die in zwei Schritten erreicht werden können: 1. XML in PDF in der Cloud, 2. Zugriff auf die konvertierte PDF -Datei auf dem Mobiltelefon konvertieren oder herunterladen.

    Was ist die Funktion der C -Sprachsumme? Was ist die Funktion der C -Sprachsumme? Apr 03, 2025 pm 02:21 PM

    Es gibt keine integrierte Summenfunktion in der C-Sprache, daher muss sie selbst geschrieben werden. Die Summe kann erreicht werden, indem das Array durchquert und Elemente akkumulieren: Schleifenversion: Die Summe wird für die Schleifen- und Arraylänge berechnet. Zeigerversion: Verwenden Sie Zeiger, um auf Array-Elemente zu verweisen, und eine effiziente Summierung wird durch Selbststillstandszeiger erzielt. Dynamisch Array -Array -Version zuweisen: Zuordnen Sie Arrays dynamisch und verwalten Sie selbst den Speicher selbst, um sicherzustellen, dass der zugewiesene Speicher befreit wird, um Speicherlecks zu verhindern.

    So konvertieren Sie XML in Bilder So konvertieren Sie XML in Bilder Apr 03, 2025 am 07:39 AM

    XML kann mithilfe eines XSLT -Konverters oder einer Bildbibliothek in Bilder konvertiert werden. XSLT -Konverter: Verwenden Sie einen XSLT -Prozessor und Stylesheet, um XML in Bilder zu konvertieren. Bildbibliothek: Verwenden Sie Bibliotheken wie Pil oder Imagemagick, um Bilder aus XML -Daten zu erstellen, z. B. Zeichnen von Formen und Text.

    Gibt es eine mobile App, die XML in PDF umwandeln kann? Gibt es eine mobile App, die XML in PDF umwandeln kann? Apr 02, 2025 pm 08:54 PM

    Eine Anwendung, die XML direkt in PDF konvertiert, kann nicht gefunden werden, da es sich um zwei grundlegend unterschiedliche Formate handelt. XML wird zum Speichern von Daten verwendet, während PDF zur Anzeige von Dokumenten verwendet wird. Um die Transformation abzuschließen, können Sie Programmiersprachen und Bibliotheken wie Python und ReportLab verwenden, um XML -Daten zu analysieren und PDF -Dokumente zu generieren.

    Gibt es eine mobile App, die XML in PDF umwandeln kann? Gibt es eine mobile App, die XML in PDF umwandeln kann? Apr 02, 2025 pm 09:45 PM

    Es gibt keine App, die alle XML -Dateien in PDFs umwandeln kann, da die XML -Struktur flexibel und vielfältig ist. Der Kern von XML zu PDF besteht darin, die Datenstruktur in ein Seitenlayout umzuwandeln, für das XML analysiert und PDF generiert werden muss. Zu den allgemeinen Methoden gehören das Parsen von XML mithilfe von Python -Bibliotheken wie ElementTree und das Generieren von PDFs unter Verwendung der ReportLab -Bibliothek. Für komplexe XML kann es erforderlich sein, XSLT -Transformationsstrukturen zu verwenden. Wenn Sie die Leistung optimieren, sollten Sie Multithread- oder Multiprozesse verwenden und die entsprechende Bibliothek auswählen.

    Empfohlenes XML -Formatierungswerkzeug Empfohlenes XML -Formatierungswerkzeug Apr 02, 2025 pm 09:03 PM

    XML -Formatierungs -Tools können Code nach Regeln eingeben, um die Lesbarkeit und das Verständnis zu verbessern. Achten Sie bei der Auswahl eines Tools auf die Anpassungsfunktionen, den Umgang mit besonderen Umständen, die Leistung und die Benutzerfreundlichkeit. Zu den häufig verwendeten Werkzeugtypen gehören Online-Tools, IDE-Plug-Ins und Befehlszeilen-Tools.

    So öffnen Sie das XML -Format So öffnen Sie das XML -Format Apr 02, 2025 pm 09:00 PM

    Verwenden Sie die meisten Texteditoren, um XML -Dateien zu öffnen. Wenn Sie eine intuitivere Baumanzeige benötigen, können Sie einen XML -Editor verwenden, z. B. Sauerstoff XML -Editor oder XMLSPY. Wenn Sie XML -Daten in einem Programm verarbeiten, müssen Sie eine Programmiersprache (wie Python) und XML -Bibliotheken (z. B. XML.etree.elementtree) verwenden, um zu analysieren.

    See all articles