Dieser Artikel behandelt die Grundlagen des Multithreadings in der Programmiersprache Python. So wie Mehrfachverarbeitung , Multithreading ist eine Möglichkeit, Multitasking zu erreichen. Beim Multithreading ist das Konzept von Threads wird eingesetzt. Lassen Sie uns zunächst das Konzept von verstehen Faden in der Computerarchitektur.
Was ist ein Prozess in Python?
In der Informatik a Verfahren ist eine Instanz eines Computerprogramms, das ausgeführt wird. Jeder Prozess besteht aus drei Grundkomponenten:
- Ein ausführbares Programm.
- Die zugehörigen, vom Programm benötigten Daten (Variablen, Arbeitsbereich, Puffer usw.)
- Der Ausführungskontext des Programms (Status des Prozesses)
Eine Einführung in Python-Threading
A Faden ist eine Entität innerhalb eines Prozesses, deren Ausführung geplant werden kann. Außerdem handelt es sich um die kleinste Verarbeitungseinheit, die in einem Betriebssystem (OS) ausgeführt werden kann. Vereinfacht ausgedrückt ist ein Thread eine Folge solcher Anweisungen innerhalb eines Programms, die unabhängig von anderem Code ausgeführt werden können. Der Einfachheit halber können Sie davon ausgehen, dass ein Thread lediglich eine Teilmenge eines Prozesses ist! Ein Thread enthält alle diese Informationen in einem Thread-Kontrollblock (TCB) :
- Thread-ID: Jedem neuen Thread wird eine eindeutige ID (TID) zugewiesen
- Stapelzeiger: Zeigt dabei auf den Stapel des Threads. Der Stapel enthält die lokalen Variablen im Gültigkeitsbereich des Threads.
- Programm zähler: ein Register, das die Adresse des Befehls speichert, der gerade von einem Thread ausgeführt wird.
- Threadstatus: kann laufend, bereit, wartend, gestartet oder erledigt sein.
- Thread-Registersatz: Dem Thread für Berechnungen zugewiesene Register.
- Zeiger des übergeordneten Prozesses: Ein Zeiger auf den Prozesssteuerungsblock (PCB) des Prozesses, in dem der Thread läuft.
Betrachten Sie das folgende Diagramm, um die Beziehung zwischen dem Prozess und seinem Thread zu verstehen:

Beziehung zwischen einem Prozess und seinem Thread
Innerhalb eines Prozesses können mehrere Threads vorhanden sein, wobei:
- Jeder Thread enthält seinen eigenen Registersatz Und lokale Variablen (im Stack gespeichert) .
- Alle Threads eines Prozesses teilen sich globale Variablen (im Heap gespeichert) und das Programmcode .
Betrachten Sie das folgende Diagramm, um zu verstehen, wie mehrere Threads im Speicher vorhanden sind:

Vorhandensein mehrerer Threads im Speicher
Eine Einführung in Threading in Python
Multithreading ist definiert als die Fähigkeit eines Prozessors, mehrere Threads gleichzeitig auszuführen. In einer einfachen Single-Core-CPU wird dies durch häufiges Wechseln zwischen Threads erreicht. Dies wird als bezeichnet Kontextwechsel . Beim Kontextwechsel wird der Status eines Threads gespeichert und der Status eines anderen Threads geladen, wann immer ein Interrupt (aufgrund von E/A oder manuell gesetzt) stattfindet. Der Kontextwechsel findet so häufig statt, dass alle Threads scheinbar parallel laufen (dies wird als „Kontextwechsel“ bezeichnet). Multitasking ).
Betrachten Sie das Diagramm unten, in dem ein Prozess zwei aktive Threads enthält:

Multithreading
Multithreading in Python
In Python , Die Einfädeln Das Modul bietet eine sehr einfache und intuitive API zum Erstellen mehrerer Threads in einem Programm. Versuchen wir, den Multithreading-Code Schritt für Schritt zu verstehen.
Schritt 1: Modul importieren
Importieren Sie zunächst das Threading-Modul.
import threading>
Schritt 2: Erstellen Sie einen Thread
Um einen neuen Thread zu erstellen, erstellen wir ein Objekt von Faden Klasse. Als Parameter werden „target“ und „args“ verwendet. Der Ziel ist die Funktion, die vom Thread ausgeführt werden soll, während die args ist die Argumente, die an die Zielfunktion übergeben werden sollen.
t1 = threading.Thread(target, args) t2 = threading.Thread(target, args)>
Schritt 3: Starten Sie einen Thread
Um einen Thread zu starten, verwenden wir die Start() Methode der Thread-Klasse.
t1.start() t2.start()>
Schritt 4: Beenden Sie die Thread-Ausführung
Sobald die Threads gestartet sind, wird auch das aktuelle Programm (Sie können es sich wie einen Hauptthread vorstellen) weiter ausgeführt. Um die Ausführung des aktuellen Programms zu stoppen, bis ein Thread abgeschlossen ist, verwenden wir die verbinden() Methode.
t1.join() t2.join()>
Daher wartet das aktuelle Programm zunächst auf den Abschluss t1 und dann t2 . Sobald sie fertig sind, werden die restlichen Anweisungen des aktuellen Programms ausgeführt.
Beispiel:
Betrachten wir ein einfaches Beispiel mit einem Threading-Modul.
Dieser Code zeigt, wie Sie mit dem Threading-Modul von Python gleichzeitig das Quadrat und die Potenz einer Zahl berechnen können. Zwei Threads, t1> Und t2> , werden erstellt, um diese Berechnungen durchzuführen. Sie werden gestartet und ihre Ergebnisse werden parallel gedruckt, bevor das Programm „Fertig!“ ausgibt. wenn beide Threads fertig sind. Threading wird verwendet, um Parallelität zu erreichen und die Programmleistung bei rechenintensiven Aufgaben zu verbessern.
Python3
import> threading> def> print_cube(num):> >print>(>'Cube: {}'> .>format>(num>*> num>*> num))> def> print_square(num):> >print>(>'Square: {}'> .>format>(num>*> num))> if> __name__>=>=>'__main__'>:> >t1>=> threading.Thread(target>=>print_square, args>=>(>10>,))> >t2>=> threading.Thread(target>=>print_cube, args>=>(>10>,))> >t1.start()> >t2.start()> >t1.join()> >t2.join()> >print>(>'Done!'>)> |
Stringformat
>
>
Ausgabe:
Square: 100 Cube: 1000 Done!>
Betrachten Sie das Diagramm unten, um besser zu verstehen, wie das obige Programm funktioniert:

Multithreading
Beispiel:
In diesem Beispiel verwenden wir os.getpid() Funktion, um die ID des aktuellen Prozesses abzurufen. Wir gebrauchen threading.main_thread() Funktion, um das Haupt-Thread-Objekt abzurufen. Unter normalen Bedingungen ist der Hauptthread der Thread, von dem aus der Python-Interpreter gestartet wurde. Name Das Attribut des Thread-Objekts wird verwendet, um den Namen des Threads abzurufen. Dann verwenden wir die threading.current_thread() Funktion zum Abrufen des aktuellen Thread-Objekts.
Betrachten Sie das unten angegebene Python-Programm, in dem wir den Thread-Namen und den entsprechenden Prozess für jede Aufgabe ausgeben.
Dieser Code zeigt, wie Sie das Threading-Modul von Python verwenden, um zwei Aufgaben gleichzeitig auszuführen. Das Hauptprogramm initiiert zwei Threads, t1> Und t2> , jeder für die Ausführung einer bestimmten Aufgabe verantwortlich. Die Threads laufen parallel und der Code liefert Informationen über die Prozess-ID und Thread-Namen. Deros>Modul wird verwendet, um auf die Prozess-ID zuzugreifen, und die ' threading'> Das Modul dient zur Verwaltung von Threads und deren Ausführung.
Python3
import> threading> import> os> def> task1():> >print>(>'Task 1 assigned to thread: {}'>.>format>(threading.current_thread().name))> >print>(>'ID of process running task 1: {}'>.>format>(os.getpid()))> def> task2():> >print>(>'Task 2 assigned to thread: {}'>.>format>(threading.current_thread().name))> >print>(>'ID of process running task 2: {}'>.>format>(os.getpid()))> if> __name__>=>=> '__main__'>:> >print>(>'ID of process running main program: {}'>.>format>(os.getpid()))> >print>(>'Main thread name: {}'>.>format>(threading.current_thread().name))> >t1>=> threading.Thread(target>=>task1, name>=>'t1'>)> >t2>=> threading.Thread(target>=>task2, name>=>'t2'>)> >t1.start()> >t2.start()> >t1.join()> >t2.join()> |
>
>
Ausgabe:
ID of process running main program: 1141 Main thread name: MainThread Task 1 assigned to thread: t1 ID of process running task 1: 1141 Task 2 assigned to thread: t2 ID of process running task 2: 1141>
Das folgende Diagramm verdeutlicht das obige Konzept:

Multithreading
Dies war also eine kurze Einführung in Multithreading in Python. Der nächste Artikel dieser Reihe befasst sich mit Synchronisation zwischen mehreren Threads . Multithreading in Python | Satz 2 (Synchronisation)
Python ThreadPool
Ein Thread-Pool ist eine Sammlung von Threads, die im Voraus erstellt werden und zur Ausführung mehrerer Aufgaben wiederverwendet werden können. Das concurrent.futures-Modul in Python stellt eine ThreadPoolExecutor-Klasse bereit, die das Erstellen und Verwalten eines Thread-Pools vereinfacht.
In diesem Beispiel definieren wir einen Funktions-Worker, der in einem Thread ausgeführt wird. Wir erstellen einen ThreadPoolExecutor mit maximal 2 Worker-Threads. Anschließend übermitteln wir mithilfe der Submit-Methode zwei Aufgaben an den Pool. Der Pool verwaltet die Ausführung der Aufgaben in seinen Arbeitsthreads. Wir verwenden die Shutdown-Methode, um zu warten, bis alle Aufgaben abgeschlossen sind, bevor der Hauptthread fortgesetzt wird.
Multithreading kann Ihnen dabei helfen, Ihre Programme effizienter und reaktionsschneller zu gestalten. Bei der Arbeit mit Threads ist jedoch Vorsicht geboten, um Probleme wie Race Conditions und Deadlocks zu vermeiden.
Dieser Code verwendet einen Thread-Pool, der mit erstellt wurde concurrent.futures.ThreadPoolExecutor> um zwei Worker-Aufgaben gleichzeitig auszuführen. Der Hauptthread wartet darauf, dass die Arbeitsthreads die Verwendung beenden pool.shutdown(wait=True)> . Dies ermöglicht eine effiziente parallele Verarbeitung von Aufgaben in einer Multithread-Umgebung.
Java-Variablentyp
Python3
import> concurrent.futures> def> worker():> >print>(>'Worker thread running'>)> pool>=> concurrent.futures.ThreadPoolExecutor(max_workers>=>2>)> pool.submit(worker)> pool.submit(worker)> pool.shutdown(wait>=>True>)> print>(>'Main thread continuing to run'>)> |
>
>Ausgabe
Worker thread running Worker thread running Main thread continuing to run>