Parallelität in Python - Threads

Wie wir wissen, ist der Faden im Allgemeinen eine sehr dünne, gedrehte Schnur, die normalerweise aus Baumwoll- oder Seidenstoff besteht und zum Nähen von Kleidung und dergleichen verwendet wird. Der gleiche Begriff Thread wird auch in der Welt der Computerprogrammierung verwendet. Wie hängen wir nun den zum Nähen von Kleidung verwendeten Faden und den für die Computerprogrammierung verwendeten Faden zusammen? Die Rollen der beiden Threads sind hier ähnlich. In der Kleidung halten Sie das Tuch zusammen und auf der anderen Seite halten Sie bei der Computerprogrammierung das Computerprogramm in einem Faden und lassen das Programm aufeinanderfolgende Aktionen oder viele Aktionen gleichzeitig ausführen.

Threadist die kleinste Ausführungseinheit in einem Betriebssystem. Es ist an sich kein Programm, sondern läuft innerhalb eines Programms. Mit anderen Worten, Threads sind nicht unabhängig voneinander und teilen Codeabschnitt, Datenabschnitt usw. mit anderen Threads. Diese Fäden werden auch als leichte Prozesse bezeichnet.

Fadenzustände

Um die Funktionalität von Threads im Detail zu verstehen, müssen wir den Lebenszyklus der Threads oder die verschiedenen Thread-Zustände kennenlernen. Normalerweise kann ein Thread in fünf verschiedenen Zuständen existieren. Die verschiedenen Zustände sind unten gezeigt -

Neues Thema

Ein neuer Thread beginnt seinen Lebenszyklus im neuen Zustand. Zu diesem Zeitpunkt wurde es jedoch noch nicht gestartet und es wurden keine Ressourcen zugewiesen. Wir können sagen, dass es nur eine Instanz eines Objekts ist.

Runnable

Wenn der neugeborene Thread gestartet wird, kann der Thread ausgeführt werden, dh er wartet darauf, ausgeführt zu werden. In diesem Status verfügt es über alle Ressourcen, aber der Taskplaner hat die Ausführung noch nicht geplant.

Laufen

In diesem Zustand macht der Thread Fortschritte und führt die Aufgabe aus, die vom Aufgabenplaner zur Ausführung ausgewählt wurde. Jetzt kann der Thread entweder in den toten Zustand oder in den nicht ausführbaren / wartenden Zustand wechseln.

Nicht laufen / warten

In diesem Zustand wird der Thread angehalten, weil er entweder auf die Antwort einer E / A-Anforderung wartet oder auf den Abschluss der Ausführung eines anderen Threads.

tot

Ein ausführbarer Thread wechselt in den Status "Beendet", wenn er seine Aufgabe abgeschlossen oder auf andere Weise beendet hat.

Das folgende Diagramm zeigt den gesamten Lebenszyklus eines Threads -

Arten von Thread

In diesem Abschnitt sehen wir die verschiedenen Arten von Threads. Die Typen werden unten beschrieben -

Threads auf Benutzerebene

Dies sind vom Benutzer verwaltete Threads.

In diesem Fall ist dem Thread-Verwaltungskern die Existenz von Threads nicht bekannt. Die Thread-Bibliothek enthält Code zum Erstellen und Zerstören von Threads, zum Weiterleiten von Nachrichten und Daten zwischen Threads, zum Planen der Thread-Ausführung sowie zum Speichern und Wiederherstellen von Thread-Kontexten. Die Anwendung beginnt mit einem einzelnen Thread.

Die Beispiele für Threads auf Benutzerebene sind -

  • Java-Threads
  • POSIX-Threads

Vorteile von Threads auf Benutzerebene

Im Folgenden sind die verschiedenen Vorteile von Threads auf Benutzerebene aufgeführt:

  • Für das Thread-Switching sind keine Berechtigungen für den Kernel-Modus erforderlich.
  • Thread auf Benutzerebene kann auf jedem Betriebssystem ausgeführt werden.
  • Die Planung kann im Thread auf Benutzerebene anwendungsspezifisch sein.
  • Threads auf Benutzerebene lassen sich schnell erstellen und verwalten.

Nachteile von Threads auf Benutzerebene

Im Folgenden sind die verschiedenen Nachteile von Threads auf Benutzerebene aufgeführt:

  • In einem typischen Betriebssystem werden die meisten Systemaufrufe blockiert.
  • Multithread-Anwendungen können Multiprocessing nicht nutzen.

Threads auf Kernebene

Vom Betriebssystem verwaltete Threads wirken auf den Kernel, der ein Betriebssystemkern ist.

In diesem Fall führt der Kernel die Thread-Verwaltung durch. Im Anwendungsbereich befindet sich kein Thread-Verwaltungscode. Kernel-Threads werden direkt vom Betriebssystem unterstützt. Jede Anwendung kann für Multithreading programmiert werden. Alle Threads in einer Anwendung werden in einem einzigen Prozess unterstützt.

Der Kernel verwaltet Kontextinformationen für den gesamten Prozess und für einzelne Threads innerhalb des Prozesses. Die Planung durch den Kernel erfolgt auf Thread-Basis. Der Kernel führt die Erstellung, Planung und Verwaltung von Threads im Kernelbereich durch. Kernel-Threads sind im Allgemeinen langsamer zu erstellen und zu verwalten als die Benutzer-Threads. Beispiele für Threads auf Kernelebene sind Windows und Solaris.

Vorteile von Threads auf Kernel-Ebene

Im Folgenden sind die verschiedenen Vorteile von Threads auf Kernelebene aufgeführt:

  • Der Kernel kann gleichzeitig mehrere Threads desselben Prozesses für mehrere Prozesse planen.

  • Wenn ein Thread in einem Prozess blockiert ist, kann der Kernel einen anderen Thread desselben Prozesses planen.

  • Kernel-Routinen selbst können Multithread-fähig sein.

Nachteile von Threads auf Kernel-Ebene

  • Kernel-Threads sind im Allgemeinen langsamer zu erstellen und zu verwalten als die Benutzer-Threads.

  • Die Übertragung der Kontrolle von einem Thread auf einen anderen innerhalb desselben Prozesses erfordert einen Moduswechsel zum Kernel.

Thread Control Block - TCB

Thread Control Block (TCB) kann als Datenstruktur im Kernel des Betriebssystems definiert werden, die hauptsächlich Informationen zum Thread enthält. In TCB gespeicherte threadspezifische Informationen würden einige wichtige Informationen zu jedem Prozess hervorheben.

Beachten Sie die folgenden Punkte in Bezug auf die in TCB enthaltenen Threads:

  • Thread identification - Dies ist die eindeutige Thread-ID (tid), die jedem neuen Thread zugewiesen wird.

  • Thread state - Es enthält die Informationen zum Status (Running, Runnable, Non-Running, Dead) des Threads.

  • Program Counter (PC) - Es zeigt auf die aktuelle Programmanweisung des Threads.

  • Register set - Es enthält die Registerwerte des Threads, die ihnen für Berechnungen zugewiesen wurden.

  • Stack Pointer- Es zeigt auf den Stapel des Threads im Prozess. Es enthält die lokalen Variablen im Bereich des Threads.

  • Pointer to PCB - Es enthält den Zeiger auf den Prozess, der diesen Thread erstellt hat.

Beziehung zwischen Prozess & Thread

Beim Multithreading sind Prozess und Thread zwei sehr eng verwandte Begriffe mit dem gleichen Ziel, dass der Computer mehr als eine Sache gleichzeitig ausführen kann. Ein Prozess kann einen oder mehrere Threads enthalten, im Gegenteil, Thread kann keinen Prozess enthalten. Beide bleiben jedoch die beiden grundlegenden Ausführungseinheiten. Ein Programm, das eine Reihe von Anweisungen ausführt, initiiert sowohl den Prozess als auch den Thread.

Die folgende Tabelle zeigt den Vergleich zwischen Prozess und Thread -

Prozess Faden
Der Prozess ist schwer oder ressourcenintensiv. Thread ist leichtgewichtig und benötigt weniger Ressourcen als ein Prozess.
Prozessumschaltung erfordert Interaktion mit dem Betriebssystem. Thread-Switching muss nicht mit dem Betriebssystem interagieren.
In mehreren Verarbeitungsumgebungen führt jeder Prozess denselben Code aus, verfügt jedoch über eigene Speicher- und Dateiressourcen. Alle Threads können denselben Satz offener Dateien und untergeordneter Prozesse gemeinsam nutzen.
Wenn ein Prozess blockiert ist, kann kein anderer Prozess ausgeführt werden, bis der erste Prozess entsperrt ist. Während ein Thread blockiert ist und wartet, kann ein zweiter Thread in derselben Task ausgeführt werden.
Mehrere Prozesse ohne Verwendung von Threads verbrauchen mehr Ressourcen. Prozesse mit mehreren Threads verbrauchen weniger Ressourcen.
In mehreren Prozessen arbeitet jeder Prozess unabhängig von den anderen. Ein Thread kann die Daten eines anderen Threads lesen, schreiben oder ändern.
Wenn sich der übergeordnete Prozess ändern würde, hätte dies keine Auswirkungen auf die untergeordneten Prozesse. Wenn sich der Hauptthread ändert, kann dies das Verhalten anderer Threads dieses Prozesses beeinflussen.
Um mit Geschwisterprozessen zu kommunizieren, müssen Prozesse prozessübergreifende Kommunikation verwenden. Threads können direkt mit anderen Threads dieses Prozesses kommunizieren.

Konzept des Multithreading

Wie bereits erwähnt, ist Multithreading die Fähigkeit einer CPU, die Verwendung des Betriebssystems durch gleichzeitiges Ausführen mehrerer Threads zu verwalten. Die Hauptidee von Multithreading besteht darin, Parallelität zu erreichen, indem ein Prozess in mehrere Threads aufgeteilt wird. Einfacher ausgedrückt können wir sagen, dass Multithreading der Weg ist, um Multitasking mithilfe des Thread-Konzepts zu erreichen.

Das Konzept des Multithreading kann anhand des folgenden Beispiels verstanden werden.

Beispiel

Angenommen, wir führen einen Prozess aus. Der Prozess könnte darin bestehen, MS Word zum Schreiben von etwas zu öffnen. In einem solchen Prozess wird ein Thread zum Öffnen von MS Word zugewiesen und ein anderer Thread wird zum Schreiben benötigt. Angenommen, wir möchten etwas bearbeiten, dann ist ein anderer Thread erforderlich, um die Bearbeitungsaufgabe usw. auszuführen.

Das folgende Diagramm hilft uns zu verstehen, wie mehrere Threads im Speicher vorhanden sind -

Wir können im obigen Diagramm sehen, dass mehr als ein Thread innerhalb eines Prozesses existieren kann, in dem jeder Thread seinen eigenen Registersatz und lokale Variablen enthält. Ansonsten teilen sich alle Threads in einem Prozess globale Variablen.

Vorteile des Multithreading

Lassen Sie uns nun einige Vorteile des Multithreading sehen. Die Vorteile sind wie folgt:

  • Speed of communication - Multithreading verbessert die Rechengeschwindigkeit, da jeder Kern oder Prozessor gleichzeitig separate Threads verarbeitet.

  • Program remains responsive - Es ermöglicht einem Programm, reaktionsschnell zu bleiben, da ein Thread auf die Eingabe wartet und ein anderer gleichzeitig eine GUI ausführt.

  • Access to global variables - Beim Multithreading können alle Threads eines bestimmten Prozesses auf die globalen Variablen zugreifen. Wenn sich die globale Variable ändert, ist sie auch für andere Threads sichtbar.

  • Utilization of resources - Das Ausführen mehrerer Threads in jedem Programm nutzt die CPU besser aus und die Leerlaufzeit der CPU wird kürzer.

  • Sharing of data - Es ist kein zusätzlicher Speicherplatz für jeden Thread erforderlich, da Threads innerhalb eines Programms dieselben Daten gemeinsam nutzen können.

Nachteile von Multithreading

Lassen Sie uns nun einige Nachteile des Multithreading sehen. Die Nachteile sind wie folgt:

  • Not suitable for single processor system - Beim Multithreading ist es schwierig, eine Leistung in Bezug auf die Rechengeschwindigkeit auf einem Einzelprozessorsystem im Vergleich zur Leistung auf einem Multiprozessorsystem zu erzielen.

  • Issue of security - Da wir wissen, dass alle Threads in einem Programm dieselben Daten gemeinsam haben, besteht immer ein Sicherheitsproblem, da jeder unbekannte Thread die Daten ändern kann.

  • Increase in complexity - Multithreading kann die Komplexität des Programms erhöhen und das Debuggen wird schwierig.

  • Lead to deadlock state - Multithreading kann das Programm zu einem potenziellen Risiko führen, den Deadlock-Status zu erreichen.

  • Synchronization required- Eine Synchronisierung ist erforderlich, um einen gegenseitigen Ausschluss zu vermeiden. Dies führt zu mehr Speicher- und CPU-Auslastung.