Geekflare wird von unserem Publikum unterstützt. Wir können Affiliate-Provisionen durch den Kauf von Links auf dieser Website verdienen.
Teilen:

Python-Threading: Eine Einführung

Threading-in-Python
Invicti Web Application Security Scanner – die einzige Lösung, die eine automatische Verifizierung von Schwachstellen mit Proof-Based Scanning™ bietet.

In diesem Tutorial erfahren Sie, wie Sie die integrierte Python verwenden einfädeln -Modul zum Erkunden von Multithreading-Fähigkeiten in Python.

Beginnend mit den Grundlagen von Prozessen und Threads lernen Sie, wie Multithreading in Python funktioniert, und verstehen gleichzeitig die Konzepte von Nebenläufigkeit und Parallelität. Anschließend erfahren Sie, wie Sie einen oder mehrere Threads in Python mithilfe der integrierten threading Modul.

Fangen wir an.

Processes vs. Threads: Differences

Was ist ein Prozess?

A Prozess is jedem Instanz eines Programms, das ausgeführt werden muss.

Es kann alles sein – ein Python-Skript oder ein Webbrowser wie Chrome bis hin zu einer Videokonferenzanwendung. Wenn Sie die starten Task-Manager auf Ihrem Computer und navigieren Sie zu Leistung -> CPUkönnen Sie die Prozesse und Threads sehen, die derzeit auf Ihren CPU-Kernen ausgeführt werden.

CPU-Proc-Threads

Prozesse und Threads verstehen

Intern hat ein Prozess einen dedizierten Speicher, der den Code und die Daten speichert, die dem Prozess entsprechen.

Ein Prozess besteht aus einem oder mehreren Themen. Ein Thread ist die kleinste Folge von Anweisungen, die das Betriebssystem ausführen kann, und stellt den Ausführungsfluss dar.

Jeder Thread hat seinen eigenen Stack und registriert sich aber nicht eine dedizierte Erinnerung. Alle einem Prozess zugeordneten Threads können auf die Daten zugreifen. Daher werden Daten und Speicher von allen Threads eines Prozesses gemeinsam genutzt.

Prozess-und-Threads

In einer CPU mit N Kernen können N Prozesse parallel zum selben Zeitpunkt ausgeführt werden. Zwei Threads desselben Prozesses können jedoch niemals parallel ausgeführt werden, sondern können gleichzeitig ausgeführt werden. Wir werden uns im nächsten Abschnitt mit dem Konzept der Nebenläufigkeit vs. Parallelität befassen.

Lassen Sie uns basierend auf dem, was wir bisher gelernt haben, die Unterschiede zwischen einem Prozess und einem Thread zusammenfassen.

Serienmäßige FunktionenProzessGewinde
MemoryDedizierte ErinnerungGeteilte Erinnerung
Art der AusführungParallel, gleichzeitigGleichzeitig; aber nicht parallel
Ausführung durchgeführt von BetriebssystemCPython-Interpreter

Multithreading in Python

In Python ist das Globale Dolmetschersperre (GIL) versichert dass einziger Thread kann die Sperre erwerben und jederzeit ausgeführt werden. Alle Threads sollten diese Sperre erwerben, um ausgeführt zu werden. Dadurch wird sichergestellt, dass zu einem bestimmten Zeitpunkt nur ein einziger Thread ausgeführt werden kann, und es wird vermieden gleichzeitig Multithreading.

Betrachten Sie zum Beispiel zwei Threads, t1 und t2, des gleichen Prozesses. Da Threads dieselben Daten teilen, wenn t1 liest einen bestimmten Wert k, t2 kann denselben Wert ändern k. Dies kann zu Deadlocks und unerwünschten Ergebnissen führen. Aber nur einer der Threads kann die Sperre erwerben und zu einem beliebigen Zeitpunkt ausgeführt werden. Dafür sorgt auch GIL Gewindesicherheit.

Wie erreichen wir also Multithreading-Fähigkeiten in Python? Um dies zu verstehen, wollen wir die Konzepte Parallelität und Parallelität diskutieren.

Nebenläufigkeit vs. Parallelität: Ein Überblick

Stellen Sie sich eine CPU mit mehr als einem Kern vor. In der Abbildung unten hat die CPU vier Kerne. Das bedeutet, dass wir zu jedem Zeitpunkt vier verschiedene Operationen parallel ausführen können.

Wenn es vier Prozesse gibt, kann jeder der Prozesse unabhängig und gleichzeitig auf jedem der vier Kerne laufen. Nehmen wir an, dass jeder Prozess zwei Threads hat.

Multicore-Parallelität

Um zu verstehen, wie Threading funktioniert, wechseln wir von der Multicore- zur Singlecore-Prozessorarchitektur. Wie erwähnt, kann bei einer bestimmten Ausführungsinstanz nur ein einziger Thread aktiv sein; aber der Prozessorkern kann zwischen den Threads umschalten. 

Code

E/A-gebundene Threads warten beispielsweise häufig auf E/A-Operationen: Einlesen von Benutzereingaben, Datenbanklesevorgänge und Dateioperationen. Während dieser Wartezeit können I/O-gebundene Threads Release die Sperre, damit der andere Thread ausgeführt werden kann. Die Wartezeit kann auch eine einfache Operation wie Schlafen sein n Sekunden.

Zusammengefasst: Während Warteoperationen gibt der Thread die Sperre frei, wodurch der Prozessorkern auf einen anderen Thread umschalten kann. Der frühere Thread nimmt die Ausführung nach Ablauf der Wartezeit wieder auf. Dieser Prozess, bei dem der Prozessorkern gleichzeitig zwischen den Threads umschaltet, erleichtert Multithreading. ✅

Wenn Sie Parallelität auf Prozessebene in Ihrer Anwendung implementieren möchten, sollten Sie die Verwendung von in Betracht ziehen Mehrfachverarbeitung stattdessen.

Python Threading Module: First Steps

Python wird mit a threading -Modul, das Sie in das Python-Skript importieren können.

import threading

Um ein Thread-Objekt in Python zu erstellen, können Sie die verwenden Thread Konstrukteur: threading.Thread(...). Dies ist die generische Syntax, die für die meisten Threading-Implementierungen ausreicht:

threading.Thread(target=...,args=...)

Hier

  • target ist das Schlüsselwortargument, das eine aufrufbare Python-Datei bezeichnet
  • args ist das Argumenttupel, das das Ziel aufnimmt.

Sie benötigen Python 3.x, um die Codebeispiele in diesem Tutorial auszuführen. Laden Sie den Code herunter und folge mit.

Define and Run Threads in Python

Lassen Sie uns einen Thread definieren, der eine Zielfunktion ausführt.

Die Zielfunktion ist some_func.

import threading
import time

def some_func():
    print("Running some_func...")
    time.sleep(2)
    print("Finished running some_func.")

thread1 = threading.Thread(target=some_func)
thread1.start()
print(threading.active_count())

Lassen Sie uns analysieren, was das obige Code-Snippet tut:

  • Es importiert die threading und time Module.
  • Die Funktion some_func hat beschreibend print() Anweisungen und beinhaltet einen Schlafvorgang für zwei Sekunden: time.sleep(n) bewirkt, dass die Funktion schläft n Sekunden.
  • Als nächstes definieren wir einen Thread thread_1 mit dem Ziel als some_func. threading.Thread(target=...) erstellt ein Thread-Objekt.
  • Hinweis: Geben Sie den Namen der Funktion und keinen Funktionsaufruf an; verwenden some_func und nicht some_func().
  • Erstellen eines Thread-Objekts nicht Starten Sie einen Thread; Aufruf der start() Methode auf dem Thread-Objekt tut.
  • Um die Anzahl der aktiven Threads zu erhalten, verwenden wir die active_count() Funktion.

Das Python-Skript wird im Hauptthread ausgeführt, und wir erstellen einen weiteren Thread (thread1), um die Funktion auszuführen some_func; Die Anzahl der aktiven Threads beträgt also zwei, wie in der Ausgabe zu sehen ist:

# Output
Running some_func...
2
Finished running some_func.

Wenn wir uns die Ausgabe genauer ansehen, sehen wir das beim Start thread1, wird die erste Druckanweisung ausgeführt. Aber während des Sleep-Vorgangs schaltet der Prozessor auf den Haupt-Thread um und gibt die Anzahl der aktiven Threads aus – ohne zu warten thread1 Ausführung zu beenden.

thread1-ex

Warten, bis Threads die Ausführung beenden

Wenn Sie möchten, thread1 Um die Ausführung zu beenden, können Sie die aufrufen join() Methode darauf nach dem Starten des Threads. Dies wird warten thread1 um die Ausführung zu beenden, ohne zum Hauptthread zu wechseln.

import threading
import time

def some_func():
    print("Running some_func...")
    time.sleep(2)
    print("Finished running some_func.")

thread1 = threading.Thread(target=some_func)
thread1.start()
thread1.join()
print(threading.active_count())

Jetzt, thread1 die Ausführung beendet hat, bevor wir die Anzahl der aktiven Threads ausgeben. Es läuft also nur der Haupt-Thread, was bedeutet, dass die Anzahl der aktiven Threads eins ist. ✅

# Output
Running some_func...
Finished running some_func.
1

How to Run Multiple Threads in Python

Als Nächstes erstellen wir zwei Threads, um zwei verschiedene Funktionen auszuführen. 

Hier count_down ist eine Funktion, die eine Zahl als Argument akzeptiert und von dieser Zahl bis Null herunterzählt.

def count_down(n):
    for i in range(n,-1,-1):
        print(i)

Wir definieren den count_up, eine weitere Python-Funktion, die von Null bis zu einer bestimmten Zahl zählt.

def count_up(n):
    for i in range(n+1):
        print(i)

📑 Bei Verwendung der range() Funktion mit der Syntax range(start, stop, step), der Endpunkt stop ist standardmäßig ausgeschlossen.

– Um von einer bestimmten Zahl auf Null herunterzuzählen, können Sie ein Negativ verwenden step Wert von -1 und setzen Sie die stop Wert auf -1, so dass Null enthalten ist.

– Ebenso bis zu zählen n, du musst die einstellen stop Wert zu n + 1. Da die Standardwerte von start und step 0 bzw. 1 sind, können Sie verwenden range(n + 1) um die Folge 0 bis n zu erhalten.

Als nächstes definieren wir zwei Threads, thread1 und thread2 um die Funktionen auszuführen count_down und count_up, beziehungsweise. Wir fügen hinzu print Aussagen und sleep Operationen für beide Funktionen.

Beachten Sie beim Erstellen der Thread-Objekte, dass die Argumente für die Zielfunktion als Tupel angegeben werden sollten – für die args Parameter. Da beide Funktionen (count_down und count_up) ein Argument aufnehmen, müssen Sie explizit ein Komma nach dem Wert einfügen. Dadurch wird sichergestellt, dass das Argument weiterhin als Tupel übergeben wird, da die nachfolgenden Elemente als abgeleitet werden None.

import threading
import time

def count_down(n):
    for i in range(n,-1,-1):
        print("Running thread1....")
        print(i)
        time.sleep(1)


def count_up(n):
    for i in range(n+1):
        print("Running thread2...")
        print(i)
        time.sleep(1)

thread1 = threading.Thread(target=count_down,args=(10,))
thread2 = threading.Thread(target=count_up,args=(5,))
thread1.start()
thread2.start()

In der Ausgabe:

  • Die Funktion count_up läuft auf thread2 und zählt bei 5 beginnend bis 0. 
  • Die count_down Funktion läuft weiter thread1 zählt von 10 auf 0 herunter.
# Output
Running thread1....
10
Running thread2...
0
Running thread1....
9
Running thread2...
1
Running thread1....
8
Running thread2...
2
Running thread1....
7
Running thread2...
3
Running thread1....
6
Running thread2...
4
Running thread1....
5
Running thread2...
5
Running thread1....
4
Running thread1....
3
Running thread1....
2
Running thread1....
1
Running thread1....
0

Sie können sehen, dass thread1 und thread2 alternativ ausführen, da beide eine Warteoperation (sleep) beinhalten. Einmal die count_up Funktion hat das Zählen bis 5 beendet, thread2 ist nicht mehr aktiv. Wir erhalten also nur die entsprechende Ausgabe thread1.

Summieren

In diesem Lernprogramm haben Sie gelernt, wie Sie das integrierte Threading-Modul von Python verwenden, um Multithreading zu implementieren. Hier ist eine Zusammenfassung der wichtigsten Takeaways:

  • Die Gewinde Konstruktor kann verwendet werden, um ein Thread-Objekt zu erstellen. Verwenden Threading.Thread(Ziel= ,args=( )) erstellt einen Thread, der die ausführt Ziel aufrufbar mit den in angegebenen Argumenten args.
  • Das Python-Programm wird auf einem Haupt-Thread ausgeführt, sodass die von Ihnen erstellten Thread-Objekte zusätzliche Threads sind. Du kannst anrufen active_count() Die Funktion gibt die Anzahl der aktiven Threads zu jeder Instanz zurück.
  • Sie können einen Thread mit starten Start() -Methode für das Thread-Objekt und warten Sie, bis die Ausführung mit der beendet ist beitreten() Methode.

Sie können nur dann Code zusätzliche Beispiele durch Optimieren der Wartezeiten, Versuchen einer anderen E/A-Operation und mehr. Achten Sie darauf, Multithreading in Ihrem nächsten zu implementieren Python-Projekte. Viel Spaß beim Programmieren!🎉

Danke an unsere Sponsoren
Weitere großartige Lektüre zum Thema Entwicklung
Treiben Sie Ihr Geschäft an
Einige der Tools und Dienste, die Ihr Unternehmen beim Wachstum unterstützen.
  • Invicti verwendet das Proof-Based Scanning™, um die identifizierten Schwachstellen automatisch zu verifizieren und innerhalb weniger Stunden umsetzbare Ergebnisse zu generieren.
    Versuchen Sie es mit Invicti
  • Web-Scraping, Wohn-Proxy, Proxy-Manager, Web-Unlocker, Suchmaschinen-Crawler und alles, was Sie zum Sammeln von Webdaten benötigen.
    Versuchen Sie es mit Brightdata
  • Semrush ist eine All-in-One-Lösung für digitales Marketing mit mehr als 50 Tools in den Bereichen SEO, Social Media und Content-Marketing.
    Versuchen Sie es mit Semrush
  • Intruder ist ein Online-Schwachstellenscanner, der Cyber-Sicherheitslücken in Ihrer Infrastruktur findet, um kostspielige Datenschutzverletzungen zu vermeiden.
    MIT DER INTELLIGENTEN SCHADENKALKULATION VON Intruder