- 1 1. Grundlagen: Was ist Multiprocessing in Python?
- 2 2. Praktischer Teil: Verwendung des multiprocessing-Moduls
- 3 3. Fortgeschrittenes: Fehlerbehandlung und Leistungsoptimierung
- 4 4. FAQ: Häufige Fragen und Lösungen
- 4.1 4.1 Multiprocessing und Multithreading in Python: Welches sollte man verwenden?
- 4.2 4.2 Warum fühlt sich multiprocessing „langsam“ an?
- 4.3 4.3 Wie teilt man Wörterbücher oder Listen in Multiprocessing?
- 4.4 4.4 Häufige Fehler bei multiprocessing.Pool und deren Behebung?
- 4.5 4.5 Wie debuggt man Multiprocessing in Python?
- 5 5. Zusammenfassung und zusätzliche Lernressourcen
- 6 5.4 Zum Abschluss
1. Grundlagen: Was ist Multiprocessing in Python?
1.1 Was ist Multiprocessing?
Multiprocessing bedeutet, mehrere Prozesse (unabhängige Ausführungseinheiten) gleichzeitig auszuführen. In Python kann Multiprocessing mit dem multiprocessing
-Modul einfach implementiert werden.
Merkmale des Multiprocessings
- Jeder Prozess hat einen unabhängigen Speicherraum
- CPU-Kerne können maximal genutzt werden
- Kommunikation zwischen Prozessen ist notwendig (
Queue
oderPipe
verwenden)
Konkrete Anwendungsszenarien
- Massenhaft rechenintensive Verarbeitung (Maschinelles Lernen, numerische Simulation)
- Aufgaben, die die CPU voll ausnutzen (Bildverarbeitung, Datenanalyse)
1.2 Unterschiede zu Multithreading
In Python gibt es auch ein paralleles Verarbeitungssystem namens „Multithreading“.Wie unterscheiden sich Multiprocessing und Multithreading?
Kriterium | Multiprocessing | Multithreading |
---|---|---|
Speicherfreigabe | Nein (unabhängige Prozesse) | Ja (innerhalb desselben Prozesses) |
Einfluss des GIL | Kein Einfluss | Betroffen |
Geeignet für CPU-bound | ◎ | ✕ |
Geeignet für I/O-bound | △ | ◎ |
Datenübertragung | Queue oder Pipe erforderlich | Shared Memory kann verwendet werden |
Was ist GIL (Global Interpreter Lock)?
Der Standard-Interpreter von Python (CPython) hat ein Mechanismus namens „GIL“, durch den auch bei Multithreading nur ein Thread gleichzeitig ausgeführt werden kann. Daher ist Multiprocessing geeignet, wenn die CPU voll ausgenutzt werden soll.
1.3 Einfaches Implementierungsbeispiel für Multiprocessing in Python
import multiprocessing
import time
def worker(n):
print(f"Prozess {n} gestartet")
time.sleep(2)
print(f"Prozess {n} beendet")
if __name__ == "__main__":
process_list = []
# 3 Prozesse erstellen
for i in range(3):
p = multiprocessing.Process(target=worker, args=(i,))
process_list.append(p)
p.start()
# Auf Beendigung aller Prozesse warten
for p in process_list:
p.join()
print("Alle Prozesse beendet")
1.4 Vorsichtsmaßnahmen beim Einsatz von Multiprocessing
1. Unter Windows ist if __name__ == "__main__":
erforderlich
In der Windows-Umgebung tritt beim Einsatz von multiprocessing.Process()
ein Fehler auf, wenn if __name__ == "__main__":
nicht geschrieben wird.
Falscher Code (verursacht Fehler)
import multiprocessing
def worker():
print("Hello from process")
p = multiprocessing.Process(target=worker)
p.start()
Dieser Code verursacht unter Windows einen Fehler.
Richtiger Code
import multiprocessing
def worker():
print("Hello from process")
if __name__ == "__main__":
p = multiprocessing.Process(target=worker)
p.start()
p.join()
Durch das Hinzufügen von if __name__ == "__main__":
funktioniert es auch unter Windows korrekt.
1.5 Zusammenfassung
- Was ist Multiprocessing? → Technik, um mehrere Prozesse parallel auszuführen
- Unterschiede zu Multithreading → Nicht beeinflusst vom GIL, geeignet für CPU-bound-Aufgaben
- Einfaches Implementierungsbeispiel in Python → Verwenden von
multiprocessing.Process()
- Vorsichtsmaßnahmen unter Windows →
if __name__ == "__main__":
ist notwendig
2. Praktischer Teil: Verwendung des multiprocessing-Moduls
2.1 Überblick über das multiprocessing-Modul
multiprocessing
Modul ist eine Standardbibliothek für die Durchführung von prozessbasierter paralleler Verarbeitung in Python.
Mit diesem Modul können Sie die CPU-Kerne voll ausnutzen und die Einschränkungen des GIL umgehen.
Hauptfunktionen von multiprocessing
Funktion | Beschreibung |
---|---|
Process | Einzelnen Prozess erstellen und ausführen |
Queue | Daten zwischen Prozessen senden und empfangen |
Pipe | Daten zwischen zwei Prozessen austauschen |
Value & Array | Geteilten Speicher zwischen Prozessen nutzen |
Pool | Einen Pool von Prozessen erstellen und effizient parallele Verarbeitung durchführen |
2.2 Grundlegende Verwendung der Process
-Klasse
Um in Python einen neuen Prozess zu erstellen, verwenden Sie die multiprocessing.Process
-Klasse.
Grundlegende Prozesserstellung
import multiprocessing
import time
def worker(n):
print(f"Prozess {n} gestartet")
time.sleep(2)
print(f"Prozess {n} beendet")
if __name__ == "__main__":
p1 = multiprocessing.Process(target=worker, args=(1,))
p2 = multiprocessing.Process(target=worker, args=(2,))
p1.start()
p2.start()
p1.join()
p2.join()
print("Alle Prozesse beendet")
2.3 Prozessinterne Kommunikation (Queue & Pipe)
Datensendung und -empfang mit Queue
import multiprocessing
def worker(q):
q.put("Hallo vom Kindprozess")
if __name__ == "__main__":
q = multiprocessing.Queue()
p = multiprocessing.Process(target=worker, args=(q,))
p.start()
p.join()
# Daten vom Kindprozess abrufen
print(q.get())
2.4 Geteilter Speicher mit Value
und Array
import multiprocessing
def worker(val, arr):
val.value = 3.14 # Wert des geteilten Speichers ändern
arr[0] = 42 # Wert des Arrays ändern
if __name__ == "__main__":
val = multiprocessing.Value('d', 0.0) # 'd' ist double-Typ
arr = multiprocessing.Array('i', [0, 1, 2]) # 'i' ist Integer-Typ
p = multiprocessing.Process(target=worker, args=(val, arr))
p.start()
p.join()
print(f"val: {val.value}, arr: {arr[:]}")
2.5 Prozessverwaltung mit der Pool
-Klasse
Parallele Verarbeitung mit Pool
import multiprocessing
def square(n):
return n * n
if __name__ == "__main__":
with multiprocessing.Pool(4) as pool:
results = pool.map(square, range(10))
print(results)
2.6 Zusammenfassung
- Mit dem
multiprocessing
-Modul kann parallele Verarbeitung einfach implementiert werden - Mit der
Process
-Klasse einzelne Prozesse erstellen - Mit
Queue
oderPipe
können Daten zwischen Prozessen geteilt werden - Mit
Value
oderArray
Speicher teilen - Mit der
Pool
-Klasse große Datenmengen effizient verarbeiten

3. Fortgeschrittenes: Fehlerbehandlung und Leistungsoptimierung
3.1 Häufige Fehler und Maßnahmen in multiprocessing
Fehler 1: Fehlender if __name__ == "__main__":
-Block im Windows-Umfeld
Fehlermeldung
RuntimeError: freeze_support() must be called if program is run in frozen mode
Lösung
import multiprocessing
def worker():
print("Hello from process")
if __name__ == "__main__": # Dies ist notwendig
p = multiprocessing.Process(target=worker)
p.start()
p.join()
Fehler 2: PicklingError (Funktion kann nicht zwischen Prozessen übergeben werden)
Fehlermeldung
AttributeError: Can't pickle local object 'main.<locals>.<lambda>'
Lösung
import multiprocessing
def square(x): # Als globale Funktion definieren
return x * x
if __name__ == "__main__":
with multiprocessing.Pool(4) as pool:
results = pool.map(square, range(10)) # Lambda vermeiden
print(results)
Fehler 3: Deadlock (Prozess bleibt hängen)
Lösung
import multiprocessing
def worker(q):
q.put("data")
if __name__ == "__main__":
q = multiprocessing.Queue()
p = multiprocessing.Process(target=worker, args=(q,))
p.start()
print(q.get()) # Daten empfangen
p.join() # Hier normal beenden
3.2 Techniken zur Leistungsoptimierung
Optimierung 1: Anzahl der Prozesse angemessen einstellen
import multiprocessing
def worker(n):
return n * n
if __name__ == "__main__":
num_workers = multiprocessing.cpu_count() # Anzahl der CPU-Kerne abrufen
with multiprocessing.Pool(num_workers) as pool:
results = pool.map(worker, range(100))
print(results)
Optimierung 2: Pool.starmap()
verwenden
import multiprocessing
def multiply(a, b):
return a * b
if __name__ == "__main__":
with multiprocessing.Pool(4) as pool:
results = pool.starmap(multiply, [(1, 2), (3, 4), (5, 6)])
print(results)
Optimierung 3: Gemeinsamen Speicher nutzen
import multiprocessing
import ctypes
def worker(shared_array):
shared_array[0] = 99 # Wert im gemeinsamen Speicher ändern
if __name__ == "__main__":
shared_array = multiprocessing.Array(ctypes.c_int, [1, 2, 3]) # Gemeinsamen Speicher erstellen
p = multiprocessing.Process(target=worker, args=(shared_array,))
p.start()
p.join()
print(shared_array[:]) # [99, 2, 3]
3.3 Zusammenfassung
multiprocessing
für häufige Fehlervermeidungsmethoden erläutert- Leistungsoptimierung-Punkte:
- Anzahl der Prozesse angemessen einstellen
- starmap() nutzen
- Mit gemeinsamem Speicher beschleunigen
4. FAQ: Häufige Fragen und Lösungen
4.1 Multiprocessing und Multithreading in Python: Welches sollte man verwenden?
Antwort
- CPU-gebunden (Prozesse mit hoher Rechenlast) → Multiprocessing (multiprocessing)
- I/O-gebunden (Datei- und Netzwerkverarbeitung) → Multithreading (threading)
Art der Verarbeitung | Geeignete Parallelverarbeitung |
---|---|
CPU-gebunden (numerische Berechnungen, Bildverarbeitung usw.) | Multiprocessing (multiprocessing) |
I/O-gebunden (Dateien, API-Anfragen usw.) | Multithreading (threading) |
4.2 Warum fühlt sich multiprocessing
„langsam“ an?
Antwort
- Hohe Kosten für die Prozesserstellung →
Pool
verwenden - Zu viele Datenkopien → Gemeinsamen Speicher (
Value
,Array
) verwenden - Viele kleine Aufgaben verarbeiten →
concurrent.futures.ThreadPoolExecutor
ausprobieren
import multiprocessing
def worker(n):
return n * n
if __name__ == "__main__":
with multiprocessing.Pool(multiprocessing.cpu_count()) as pool:
results = pool.map(worker, range(100))
print(results)
4.3 Wie teilt man Wörterbücher oder Listen in Multiprocessing?
Antwort
multiprocessing.Manager()
verwenden
import multiprocessing
def worker(shared_list):
shared_list.append(100) # Gemeinsame Liste aktualisieren
if __name__ == "__main__":
with multiprocessing.Manager() as manager:
shared_list = manager.list([1, 2, 3])
p = multiprocessing.Process(target=worker, args=(shared_list,))
p.start()
p.join()
print(shared_list) # [1, 2, 3, 100]
4.4 Häufige Fehler bei multiprocessing.Pool
und deren Behebung?
Fehler | Ursache | Lösung |
---|---|---|
AttributeError: Can't pickle local object | lambda oder lokale Funktionen übergeben | Globale Funktionen verwenden |
RuntimeError: freeze_support() must be called | Windows-Umgebung ohne if __name__ == "__main__": | if __name__ == "__main__": hinzufügen |
EOFError: Ran out of input | Pool , Prozesse wurden nicht normal beendet | pool.close() und pool.join() ordnungsgemäß aufrufen |
4.5 Wie debuggt man Multiprocessing in Python?
Antwort
multiprocessing.log_to_stderr()
nutzen
import multiprocessing
import logging
def worker(n):
logger = multiprocessing.get_logger()
logger.info(f"Prozess {n} wird ausgeführt")
if __name__ == "__main__":
multiprocessing.log_to_stderr(logging.INFO) # Logging aktivieren
p = multiprocessing.Process(target=worker, args=(1,))
p.start()
p.join()
5. Zusammenfassung und zusätzliche Lernressourcen
5.1 Zusammenfassung dieses Artikels
Grundlagen des Multiprocessing
- Was ist Multiprocessing? → Technik, um mehrere Prozesse parallel auszuführen und die CPU optimal zu nutzen
- Unterschiede zum Multithreading
- Multiprocessing → Geeignet für CPU-gebundene Aufgaben (numerische Berechnungen, Bildverarbeitung usw.)
- Multithreading → Geeignet für I/O-gebundene Aufgaben (Dateiverarbeitung, Netzwerkkommunikation usw.)
multiprocessing
Modul-Verwendung
- Mit der
Process
-Klasse einzelne Prozesse erstellen - Mit
Queue
oderPipe
Daten zwischen Prozessen senden und empfangen Value
oderArray
nutzen, um gemeinsamen Speicher zu verwenden- Mit der
Pool
-Klasse effiziente parallele Verarbeitung durchführen
Fehlerbehandlung und Performance-Optimierung
- Häufige Fehler
if __name__ == "__main__":
nicht schreiben führt zu Fehlern unter Windowslambda
-Funktionen oder lokale Funktionen verursachen PicklingErrorQueue.get()
vergessen führt zu Deadlocks- Performance-Optimierung
Pool
nutzen, um die Kosten der Prozesserstellung zu reduzierenstarmap()
verwenden, um mehrere Argumente zu übergebenmultiprocessing.shared_memory
nutzen, um den Overhead durch Datenkopien zu reduzieren
5.2 Zusätzliche Lernressourcen
1. Offizielle Python-Dokumentation
2. Online-Tutorials
5.3 Für die zukünftige Nutzung
Durch die angemessene Nutzung von Pythons multiprocessing
kann die CPU effizient genutzt werden, um leistungsstarke Programme zu erstellen.
Als Nächstes zu lernende Techniken
- Asynchrone Verarbeitung (asyncio) → Parallelisierung von I/O-gebundenen Aufgaben
- concurrent.futures → Integriertes Management von Threads und Prozessen
5.4 Zum Abschluss
In diesem Artikel haben wir „Python Multiprocessing“ von den Grundlagen über die Praxis bis hin zu Anwendungen detailliert erläutert. Nutzen Sie das in diesem Artikel erlernte Wissen und wenden Sie es in realen Projekten an! 🚀