Larry Wall gibt den Rakudo-Perl-6-Compiler auf MoarVM für den produktiven Einsatz frei

Seite 4: Parallelität

Inhaltsverzeichnis

Mit der parallelen und asynchronen Programmierung hält es Perl 6 wie mit den Typen: Ohne Zutun kommt sie in Maßen zum Einsatz. Der Entwickler kann die Verwendung graduell steigern.

Zwar gibt es eine Klasse von Listen-Operatoren, deren Arbeit Rakudo automatisch prarallelisieren soll, aber das geschieht bisher noch nicht. Die Vorgehensweise ist jedoch weiterhin in Planung. Wer im C++-Stil mehrere CPU-Kerne belegen will, dem stehen auch in Perl 6 Threads, Locks und Semaphore zur Verfügung. Am interessantesten dürften jedoch die Klassen Promise, Channel und Supply sein, die einfach bedienbare und kombinierbare Mechanismen bereitstellen.

    my $promise1 = start tuwas($daten, ...); # Aufruf einer gewöhnlichen Routine
my $promise2 = start tumehr($daten, ...); # mit sehr normalen Daten
    my (@ergebnis1, @ergebnis2) = await $promise1, $promise2;

Etwas mehr Kontrolle erlauben die Methoden .race und .hyper. Sie eröffnen eine, alle Details regelnde, HyperSeq. Mit den optionalen Parametern darf man die Größe der Datenpakete (batch) und Anzahl der belegten Kerne (degree) festlegen. Im Gegensatz zu .hyper signalisiert der Programmierer mit .race, dass ihm nichts an der Reihenfolge der Ergebnisse liegt.

   my $zwischenergebnis = tuwas($daten, ...).race(batch => 12, degree => 4);
my $zwerg2 = tunochmehr($zwischenergebnis);
my $zwerg3 = ...

Sobald tuwas hier die ersten 12 Werte abgibt, füttern die Hyperseq tunochmehr (einzeln) damit, und mit den Ergebnissen die nächste sub und so weiter. Falls tuwas schon die nächsten 12 Werte bereitstellt, bevor die ersten 12 durchgelaufen sind, erzeugt Perl ein "paralleles Fließband" (hier maximal 4). All das verträgt sich mit anderen asynchronen Anweisungen, da alles über den $*SCHEDULER geregelt wird, auf den der Programmierer auch direkt Zugriff hat.

Designziel war es, die Konstrukte so gewöhnlich wie möglich erscheinen zu lassen. Aus asynchronen Datenkanälen wie einem Supply lassen sich wie gewohnt map, grep oder uniq anwenden und

    whenever IO::Notification.watch-path('.') { ...

ist mit einer for-Schleife vergleichbar, die ausgeführt wird, wann immer dieser Supply einen Wert liefert.