Geschichte der Frage
Threads (Threads) wurden in Perl als Reaktion auf die Notwendigkeit entwickelt, konkurrierende Berechnungen und parallele Arbeiten mit Ressourcen in Multitasking-Programmen zu organisieren. Das standardisierte Modul threads ist seit Version 5.8 stabil in Perl enthalten und hat sich allmählich von Experimenten mit ithreads zu einem universellen threads::shared entwickelt.
Problem
Die erste Schwierigkeit ist, dass Perl Threads nicht nativ unterstützt, wie es in Sprachen wie Java der Fall ist. Threads in Perl arbeiten durch das Kopieren des Stacks und der Daten jedes Threads, was Overhead schafft und die direkte Arbeit mit globalen Variablen unmöglich macht (außer bei Variablen mit spezieller Bindung über threads::shared). Perl garantiert auch nicht die unabhängige Arbeit von Threads bei gleichzeitiger Datenaufzeichnung ohne explizite Synchronisierung.
Lösung
Zur Organisation von Threads wird das Modul threads und das zusätzliche Modul threads::shared zum Austausch von Daten zwischen Threads verwendet. Die Gewährleistung von Synchronisierung und Datenintegrität liegt in der Verantwortung des Entwicklers, oft durch den Einsatz von Locks.
Beispielcode:
use threads; use threads::shared; my $counter :shared = 0; sub increment { lock($counter); $counter++; } my @threads; for (1..10) { push @threads, threads->create(\&increment); } $_->join for @threads; print "Counter: $counter ";
Wesentliche Merkmale:
Kann man beliebige globale Variablen ohne threads::shared verwenden und erwarten, dass Threads die Änderungen sehen?
Nein. Globale Variablen werden in jeden Thread individuell kopiert. Der Austausch erfolgt nur über threads::shared oder andere IPC (über Prozesse).
Ist es erlaubt, fork und threads in demselben Perl-Skript zu verwenden?
Es wird nicht empfohlen, fork und threads zu mischen, da dies zu unvorhersehbaren Fehlern und instabilen Verhalten führt. Perl warnt offiziell davor, diese Techniken gleichzeitig zu verwenden.
Kann man komplexe Datenstrukturen zwischen Threads über Standardreferenzen (Reference) übergeben?
Nein. Perl kopiert rekursiv geschachtelte Strukturen nicht automatisch, und solche Versuche führen zu Fehlern oder unintuitiven Ergebnissen. Dafür sind tiefes Kopieren und die Verwendung von shared-Ressourcen erforderlich.
Ein Entwickler hat eine einfache Warteschlange über ein Array erstellt, das gleichzeitig von mehreren Threads ohne threads::shared aktualisiert wurde. Die Daten wurden oft beschädigt, und die Ergebnisse des Programms waren inkorrekt.
Vorteile:
Nachteile:
Verwendung von threads::shared mit Locks, die gesamte Warteschlange wurde als shared deklariert, die Synchronisierung erfolgte über einen Lock. Das Programm arbeitete stabil, selbst unter intensiver Belastung.
Vorteile:
Nachteile: