Im März 2024 führt Python wie seit vielen Monaten den Tiobe Programming Community Index an, während Java den vierten Platz belegt. Haskell hingegen spielt eine eher untergeordnete Rolle und landet lediglich auf dem 30. Platz. Doch unser Multithreading-Benchmark-Test wird zeigen, dass Haskell bei der Nebenläufigkeit zu Unrecht vernachlässigt wird.
In der Programmierung wird zwischen parallelen Berechnungen (Parallelism) und gleichzeitig ausgeführten Aufgaben (Concurrency bzw. Multithreading) unterschieden. Beide haben unterschiedliche Anwendungsbereiche: Parallele Programme erreichen hohe Geschwindigkeiten durch die intensive Nutzung von Hardware-Ressourcen, insbesondere mehrerer CPU-Kerne. Ein Programm kann sein Ziel schneller erreichen, indem es die Berechnung in mehrere Teile aufteilt und diese an die einzelnen CPU-Kerne delegiert. Die parallele Programmierung ist besonders effizient und wird von Sortieralgorithmen zum Beispiel stark profitiert.
Im Gegensatz dazu basiert Multithreading bzw. Concurrency auf der Verwendung von mehreren Threads. Diese Threads laufen vom Konzept her gleichzeitig ab, wodurch ihre Auswirkungen sich überlappen können. Ob alle diese Aufgaben tatsächlich gleichzeitig ausgeführt werden, hängt von der Implementierung ab. Ein Programm, das auf Multithreading basiert, kann entweder auf einem einzelnen CPU-Kern durch verschachtelte Ausführung laufen oder auf mehrere Kerne oder physische CPUs verteilt werden.
Multithreading wird insbesondere dann eingesetzt, wenn das Programm mit mehreren externen Agenten interagieren soll, die unabhängig voneinander handeln. Ein Beispiel hierfür sind Zugriffe mehrerer externer Clients auf einen Datenbank-Server, die mittels Multithreading erfolgen. Ein weiterer Vorteil von Multithreading besteht in der Modularität solcher Programme. Ein Thread, der mit Nutzern kommuniziert, unterscheidet sich beispielsweise von einem Thread, der mit der Datenbank interagiert. Ohne Multithreading müssten Entwicklerinnen und Entwickler bei Client/Server-Anwendungen beispielsweise auf ereignisgesteuerte Schleifen und Rückverweise zurückgreifen, was deutlich mühsamer ist.
Die Implementierungen von Concurrency bzw. Parallelität variieren von Sprache zu Sprache erheblich in Bezug auf die verwendeten Mechanismen und die daraus resultierende Komplexität (siehe Abbildung 1). In Haskell wird beispielsweise das Control.Parallel-Modul verwendet, um gängige Multithreading-Probleme wie Deadlocks und Race Conditions zu vermeiden.
Schlagwörter: Concurrency + Python + Tiobe
Wie bewerten Sie den Schreibstil des Artikels?
