Python-Thread-Priorität

Abid Ullah 21 Juni 2023
  1. Threading in Python
  2. Steuern der Planungspriorität von Python-Threads
Python-Thread-Priorität

Dieser Artikel soll erklären, wie wir das Scheduling-Threading in Python verwenden können, um es zu einer Priorität zu machen. Hier sprechen wir über das Planen eines Prioritäts-Threads in Python und dessen Verwendung mit einem guten Beispielprogramm.

Mit Python-Threading können wir verschiedene Teile unseres Programms gleichzeitig ausführen, was das Design Ihres Programms vereinfacht. Wir zeigen Ihnen, wie Sie Threads verwenden können, um Ihr Python-Programm zu beschleunigen, wenn Sie sich mit Python auskennen.

Threading in Python

Threading ist die Fähigkeit, mehrere Anweisungen gleichzeitig auszuführen. Wie wir in diesem Artikel untersuchen, können wir die Threads priorisieren, indem wir die Planung anpassen.

Zur Implementierung von Python-Threads wird eine globale Interpretersperre (GIL) verwendet, was bedeutet, dass die Priorität eines Threads nicht gesteuert werden kann. Um Threads mit einer Priorität zu steuern, müssen wir ein implizites Prioritätssystem erstellen.

Beim Threading können Sie sich zwei (oder mehr) Prozessoren vorstellen, die gleichzeitig auf Ihrem Programm laufen und jeweils eine unabhängige Aufgabe ausführen.

Das kommt der Wahrheit sehr nahe. Jeder Thread wird gleichzeitig auf einem Prozessor ausgeführt, sogar auf verschiedenen Prozessoren.

Um mehrere Aufgaben gleichzeitig auszuführen, benötigen Sie eine nicht standardmäßige Python-Implementierung, Ihr Code muss möglicherweise in einer anderen Sprache geschrieben werden, oder Sie müssen möglicherweise Multiprocessing mit zusätzlichem Overhead verwenden.

Die C-Implementierung von Python unterstützt Threading nicht immer, sodass Threading möglicherweise nicht alle Aufgaben beschleunigt. GIL-Interaktionen begrenzen die Anzahl der Python-Threads, die gleichzeitig ausgeführt werden können.

Im Allgemeinen ist Threading eine geeignete Wahl für Aufgaben, die viel Zeit damit verbringen, auf externe Ereignisse zu warten. Es ist möglich, dass Probleme, die eine hohe CPU-Rechenleistung erfordern, aber wenig Zeit damit verbringen, auf externe Ereignisse zu warten, nicht so schnell ausgeführt werden wie andere.

Steuern der Planungspriorität von Python-Threads

Es ist entscheidend sicherzustellen, dass wir mit der richtigen Version von Python arbeiten. Wir verwenden speziell für diesen Artikel die Version 3.10.4.

Es ist möglich, die aktuell installierte Python-Version zu überprüfen, indem Sie den folgenden Befehl im Terminal ausführen.

python --version

Importieren nützlicher Bibliotheken

Der nächste Schritt besteht darin, zu lernen, wie man einen Thread mit Planungspriorität erstellt, nachdem man verstanden hat, was ein Thread ist. Die meisten der Grundelemente, die Sie in diesem Artikel sehen werden, werden von der Python-Standardbibliothek durch Threading bereitgestellt.

In diesem Modul bietet Thread eine schöne Schnittstelle für die Interaktion mit Threads und kapselt sie gut.

Jetzt fahren wir mit der nächsten Phase des Programms fort, in der wir die Bibliotheken importieren, die zum Planen der Prioritäten von Python-Threads erforderlich sind.

Beispielcode:

import time
from threading import Thread
from time import sleep

Es ist möglich, einen separaten Thread zu starten, indem Sie die Instanz Thread verwenden und ihr .start() mitteilen.

Beispielcode:

import logging
import threading
import time


def the_thread_function(name):
    logging.info("The thread %s: Beginning now", name)
    time.sleep(2)
    logging.info("The Thread %s: Ends", name)


if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")
    logging.info("Main    : Now before creating a thread")
    x = threading.Thread(target=the_thread_function, args=(1,))
    logging.info("Main    : Earlier than running threading")
    x.start()
    logging.info("Main    : Now wait for the thread to End")
    # x.join()
    logging.info("Main    : All Finish")

Ausgang:

17:06:51: Main    : Now before creating a thread
17:06:51: Main    : Earlier than running threading
17:06:51: The thread 1: Beginning now
17:06:51: Main    : Now wait for the thread to End
17:06:51: Main    : All Finish
17:06:53: The Thread 1: Ends

In den Protokollierungsanweisungen können Sie sehen, dass der Hauptabschnitt den Thread erstellt und startet: Sie erstellen einen Thread, indem Sie ihm eine Argumentliste und die Funktion übergeben, die Sie aufrufen möchten.

In diesem Fall wird der Thread angewiesen, thread_function() auszuführen und ihm 1 als Argument zu übergeben.

Arbeiten mit vielen Threads Zeitplanpriorität in Python

Derzeit funktioniert der Beispielcode nur mit zwei Threads, dem Hauptthread und dem Thread, den Sie mit dem Threading-Objekt Thread gestartet haben. Sie werden oft viele Threads starten und sie an interessanten Dingen arbeiten lassen wollen.

Sehen wir uns als Nächstes eine einfachere Methode dafür an. Beginnen wir mit dem schwierigeren Weg.

Beispielcode:

import logging
import threading
import time


def thread_function(name):
    logging.info("Thread %s: Beginning", name)
    time.sleep(2)
    logging.info("Thread %s: Ending", name)


if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO, datefmt="%H:%M:%S")
    threads = list()
    for index in range(3):
        logging.info("Main    : create and start thread %d.", index)
        x = threading.Thread(target=thread_function, args=(index,))
        threads.append(x)
        x.start()
    for index, thread in enumerate(threads):
        logging.info("Main    : Before joining thread %d.", index)
        thread.join()
        logging.info("Main    : thread %d end", index)

Ausgang:

17:09:01: Main    : create and start thread 2.
17:09:01: Thread 2: Beginning
17:09:01: Main    : Before joining thread 0.
17:09:03: Thread 0: Ending
17:09:03: Main    : thread 0 end
17:09:03: Main    : Before joining thread 1.
17:09:03: Thread 1: Ending
17:09:03: Main    : thread 1 end
17:09:03: Main    : Before joining thread 2.
17:09:03: Thread 2: Ending
17:09:03: Main    : thread 2 end

Wir starten einen Thread genauso, wie wir zuvor einen Thread gestartet haben, indem wir ein Thread-Objekt erstellen und dann .start() aufrufen. Das Führen einer Liste von Thread-Objekten ermöglicht es dem Programm, später mit .join() auf sie zu warten.

Wenn Sie sich die Ausgabe genau ansehen, werden Sie feststellen, dass alle drei Threads in der erwarteten Reihenfolge gestartet werden. In diesem Fall enden sie jedoch in umgekehrter Reihenfolge!

Mehrere Läufe werden die verschiedenen Aufträge produzieren und ausgeben. Achten Sie auf die Meldung Thread x: Nearing End, die Ihnen mitteilt, wann jeder Thread zu Ende geht.

Betriebssysteme bestimmen die Reihenfolge, in der Threads ausgeführt werden, was ziemlich schwer vorherzusagen ist. Die Verwendung von Threading in Algorithmen kann (und wird wahrscheinlich) von Lauf zu Lauf variieren, also denken Sie daran, wenn Sie Algorithmen entwickeln.

Es ist eine großartige Sache, dass Python mehrere Primitive bereitstellt, um Threads zu koordinieren und sie miteinander zu koordinieren. Wir sehen uns zuerst an, wie wir die Verwaltung einer Gruppe von Threads vereinfachen können.

Erstellen der Klasse Worker

Diese worker-Klasse ermöglicht es uns, das Skript so einzustellen, dass jeder Thread seine Ausführungszeit haben kann. Wie in Form eines Ergebnisses lassen wir die anderen Threads länger schlafen, wenn ein Thread eine höhere Priorität hat.

Die Klasse Worker ist eine einfache MFC-Klasse, die Ihnen beim Multithreading hilft. Jedes Objekt, dessen Thread Arbeiten ausführen muss, erbt von der Klasse Worker.

Verwenden Sie die Do-Work-Funktion, um den langen Prozess auszuführen - und verwenden Sie dann Start/Stop/Pause auf dem Objekt, um ihn auszuführen.

Beispielcode:

import time
from threading import Thread
from time import sleep


class Worker(Thread):
    def __init__(self, pri):
        Thread.__init__(self)
        self.pri = pri

    def run(self):
        for i in range(20):
            sleep(1.0 * self.pri)
            print(" -thread with priority:", self.pri)


w1 = Worker(1.0)
w2 = Worker(0.75)
w3 = Worker(0.5)
start = time.time()
w1.start()
w2.start()
w3.start()
end = time.time()

Als Teil dieses Schritts haben wir Worker initialisiert. Anschließend haben wir mehrere Threads mit unterschiedlichen Prioritäten erstellt.

Die Worker-Threads werden nun wie folgt ausgeführt:

Output exceeds the size limit. Open the full output data in a text editor
 -thread with priority: 0.5
 -thread with priority: 0.75
 -thread with priority: 1.0
 -thread with priority: 0.5
 -thread with priority: 0.75
 -thread with priority: 0.5
 -thread with priority: 1.0
 -thread with priority: 0.5
 -thread with priority: 0.75
 -thread with priority: 0.5
 -thread with priority: 1.0
 -thread with priority: 0.75

Im Durchschnitt sehen wir, dass die Threads mit 0,5 und 0,75 Prioritäten nach der Ausführung häufiger aufgerufen wurden als die Threads mit 1,0 Prioritäten, indem wir uns den Ausgabe-Trace der Thread-Ausführung ansehen.

Das folgende Beispiel zeigt, wie ein einfaches Python-Skript einen Python-Thread basierend auf einer Priorität planen kann.

Wir haben jetzt einige Beispiele für Python-Threading und das Erstellen von Thread-Programmen mit vielen Threads, Planungsprioritäten und den Problemen, die sie lösen, gesehen. Auch die Verwendung der Klassen start(), join(), time(), worker und vieler anderer Methoden wurde demonstriert.

Wir hoffen, dass Sie diesen Artikel hilfreich finden, um zu verstehen, wie die Threads in Python verwendet werden.

Autor: Abid Ullah
Abid Ullah avatar Abid Ullah avatar

My name is Abid Ullah, and I am a software engineer. I love writing articles on programming, and my favorite topics are Python, PHP, JavaScript, and Linux. I tend to provide solutions to people in programming problems through my articles. I believe that I can bring a lot to you with my skills, experience, and qualification in technical writing.

LinkedIn

Verwandter Artikel - Python Thread