Ich habe ein Powershell-Skript, um eine Stapelverarbeitung für eine Reihe von Bildern durchzuführen, und ich möchte eine parallele Verarbeitung durchführen. Powershell scheint einige Hintergrundverarbeitungsoptionen wie Startjob, Wartejob usw. zu haben, aber die einzige gute Ressource, die ich für die parallele Arbeit gefunden habe, war das Schreiben des Textes eines Skripts und das Ausführen dieser ( PowerShell Multithreading ).
Im Idealfall möchte ich etwas Ähnliches wie parallele foreach in .net 4.
Etwas ziemlich Scheinloses wie:
foreach-parallel -threads 4 ($file in (Get-ChildItem $dir))
{
.. Do Work
}
Vielleicht wäre ich besser dran, wenn ich einfach auf c # fallen würde ...
multithreading
powershell
parallel-processing
Alan Jackson
quelle
quelle
receive-job (wait-job ($a = start-job { "heyo!" })); remove-job $a
oder$a = start-job { "heyo!" }; wait-job $a; receive-job $a; remove-job $a
Beachten Sie auch, dassreceive-job
Sie möglicherweise gar nichts bekommen , wenn Sie anrufen, bevor der Job beendet ist.(get-job $a).jobstateinfo.state;
Antworten:
Sie können parallele Jobs in Powershell 2 mithilfe von Hintergrundjobs ausführen . Schauen Sie sich Start-Job und die anderen Job-Cmdlets an.
quelle
Test-Path "\\$_\c$\Something"
Ich würde erwarten, dass sie$_
in das aktuelle Element erweitert wird. Dies ist jedoch nicht der Fall. Stattdessen wird ein leerer Wert zurückgegeben. Dies scheint nur innerhalb von Skriptblöcken zu geschehen. Wenn ich diesen Wert unmittelbar nach dem ersten Kommentar schreibe, scheint er korrekt zu funktionieren.Die Antwort von Steve Townsend ist theoretisch richtig, aber nicht in der Praxis, wie @likwid hervorhob. Mein überarbeiteter Code berücksichtigt die Job-Kontext-Barriere - nichts überschreitet diese Barriere standardmäßig! Die automatische
$_
Variable kann somit in der Schleife verwendet werden, kann jedoch nicht direkt im Skriptblock verwendet werden, da sie sich in einem separaten Job befindet, der vom Job erstellt wurde.Um Variablen aus dem übergeordneten Kontext an den untergeordneten Kontext zu übergeben, verwenden Sie den
-ArgumentList
Parameter onStart-Job
, um sie zu senden, und verwenden Sie sieparam
im Skriptblock, um sie zu empfangen.(Im Allgemeinen möchte ich einen Verweis auf die PowerShell-Dokumentation als unterstützenden Beweis geben, aber leider war meine Suche erfolglos. Wenn Sie zufällig wissen, wo die Kontexttrennung dokumentiert ist, geben Sie hier einen Kommentar ab, um mich zu informieren!)
quelle
Start-Job -FilePath script.ps1 -ArgumentList $_
http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0
Ich habe einen invoke-async erstellt, mit dem Sie mehrere Skriptblöcke / Cmdlets / Funktionen gleichzeitig ausführen können. Dies ist ideal für kleine Jobs (Subnetz-Scan oder WMI-Abfrage für Hunderte von Computern), da der Aufwand für die Erstellung eines Runspace im Vergleich zur Startzeit des Startjobs ziemlich drastisch ist. Es kann so verwendet werden.
mit scriptblock,
nur Cmdlet / Funktion
quelle
Es gibt heutzutage so viele Antworten darauf:
foreach-object -parallel
Alternative für # 4Hier sind Workflows mit buchstäblich einer foreach-Parallele:
Oder ein Workflow mit einem parallelen Block:
Hier ist eine API mit Runspaces-Beispiel:
quelle
Die Einrichtung von Hintergrundjobs ist teuer und nicht wiederverwendbar. PowerShell MVP Oisin Grehan hat ein gutes Beispiel für PowerShell-Multithreading.
(Die Website vom 25.10.2010 ist nicht verfügbar, aber über das Webarchiv zugänglich.)
Ich habe hier ein angepasstes Oisin-Skript zur Verwendung in einer Datenladeroutine verwendet:
http://rsdd.codeplex.com/SourceControl/changeset/view/a6cd657ea2be#Invoke-RSDDThreaded.ps1
quelle
Um frühere Antworten zu vervollständigen, können Sie auch
Wait-Job
warten, bis alle Jobs abgeschlossen sind:quelle
In Powershell 7 können Sie ForEach-Object -Parallel verwenden
quelle
Wenn Sie die neueste plattformübergreifende Powershell (die Sie übrigens verwenden sollten) https://github.com/powershell/powershell#get-powershell verwenden , können Sie einzelne hinzufügen
&
, um parallele Skripts auszuführen. (Verwenden;
Zum sequentiellen Ausführen verwenden)In meinem Fall musste ich 2 npm-Skripte parallel ausführen:
npm run hotReload & npm run dev
Sie können npm auch
powershell
für seine Skripte einrichten (standardmäßigcmd
unter Windows).Führen Sie den Projektstammordner aus:
npm config set script-shell pwsh --userconfig ./.npmrc
und verwenden Sie dann den einzelnen npm-Skriptbefehl:npm run start
quelle