Mam skrypt PowerShell do przetwarzania wsadowego na kilku obrazach i chciałbym przeprowadzić równoległe przetwarzanie. Wydaje się, że Powershell ma pewne opcje przetwarzania w tle, takie jak start-job, wait-job itp., Ale jedynym dobrym źródłem, które znalazłem do wykonywania równoległej pracy, było napisanie tekstu skryptu i uruchomienie go ( wielowątkowość PowerShell )
Idealnie, chciałbym coś podobnego do równoległego foreach w .net 4.
Coś całkiem pozornego, jak:
foreach-parallel -threads 4 ($file in (Get-ChildItem $dir))
{
.. Do Work
}
Może lepiej byłoby, gdybym zszedł do C # ...
multithreading
powershell
parallel-processing
Alan Jackson
źródło
źródło
receive-job (wait-job ($a = start-job { "heyo!" })); remove-job $a
lub$a = start-job { "heyo!" }; wait-job $a; receive-job $a; remove-job $a
Zauważ również, że jeśli zadzwoniszreceive-job
przed zakończeniem zadania, możesz w ogóle nic nie otrzymać.(get-job $a).jobstateinfo.state;
Odpowiedzi:
Możesz wykonywać równoległe zadania w programie PowerShell 2 przy użyciu zadań w tle . Sprawdź Start-Job i inne polecenia cmdlet Job.
źródło
Test-Path "\\$_\c$\Something"
spodziewałbym się, że rozszerzy$_
się do bieżącej pozycji. Jednak tak nie jest. Zamiast tego zwraca pustą wartość. Wydaje się, że dzieje się to tylko z poziomu bloków skryptu. Jeśli wypiszę tę wartość natychmiast po pierwszym komentarzu, wydaje się, że działa poprawnie.Odpowiedź Steve'a Townsenda jest poprawna w teorii, ale nie w praktyce, jak zauważył @likwid. Mój poprawiony kod uwzględnia barierę związaną z kontekstem pracy - domyślnie nic nie przekracza tej bariery!
$_
Zmienna automatyczna może być zatem używana w pętli, ale nie może być używana bezpośrednio w bloku skryptu, ponieważ znajduje się w oddzielnym kontekście utworzonym przez zadanie.Aby przekazać zmienne z kontekstu nadrzędnego do kontekstu podrzędnego, użyj
-ArgumentList
parametru on,Start-Job
aby je wysłać, i użyjparam
wewnątrz bloku skryptu, aby je odebrać.(Generalnie lubię podawać odniesienie do dokumentacji PowerShell jako dowód potwierdzający, ale niestety moje poszukiwania były bezowocne. Jeśli wiesz, gdzie udokumentowano separację kontekstów, opublikuj tutaj komentarz, aby dać mi znać!)
źródło
Start-Job -FilePath script.ps1 -ArgumentList $_
http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0
Stworzyłem invoke-async, który umożliwia uruchamianie wielu bloków skryptów / poleceń cmdlet / funkcji w tym samym czasie. jest to świetne rozwiązanie w przypadku małych zadań (skanowanie podsieci lub kwerendy wmi na setkach maszyn), ponieważ obciążenie związane z tworzeniem obszaru roboczego w porównaniu z czasem uruchamiania zadania jest dość drastyczne. Może być używany w ten sposób.
z blokiem skryptów,
po prostu polecenie cmdlet / funkcja
źródło
W dzisiejszych czasach jest tak wiele odpowiedzi na to pytanie:
foreach-object -parallel
alternatywę dla # 4Oto przepływy pracy z dosłownie paralelą foreach:
Lub przepływ pracy z równoległym blokiem:
Oto przykład interfejsu API z obszarami uruchomieniowymi:
źródło
Zadania w tle są drogie w konfiguracji i nie nadają się do ponownego wykorzystania. PowerShell MVP Oisin Grehan ma dobry przykład wielowątkowości programu PowerShell.
(Witryna 25.10.2010 nie działa, ale jest dostępna za pośrednictwem archiwum internetowego).
Użyłem dostosowanego skryptu Oisin do użycia w procedurze ładowania danych tutaj:
http://rsdd.codeplex.com/SourceControl/changeset/view/a6cd657ea2be#Invoke-RSDDThreaded.ps1
źródło
Aby uzupełnić poprzednie odpowiedzi, możesz także użyć opcji
Wait-Job
czekania na zakończenie wszystkich zadań:źródło
W programie PowerShell 7 można użyć funkcji ForEach-Object -Parallel
źródło
Jeśli używasz najnowszej wieloplatformowej powłoki PowerShell (którą powinieneś btw) https://github.com/powershell/powershell#get-powershell , możesz dodać pojedynczy,
&
aby uruchamiać równoległe skrypty. (Służy;
do uruchamiania sekwencyjnego)W moim przypadku potrzebowałem uruchomić równolegle 2 skrypty npm:
npm run hotReload & npm run dev
Możesz także skonfigurować npm do używania
powershell
dla swoich skryptów (domyślnie używacmd
w systemie Windows).Uruchom z folderu głównego projektu:
npm config set script-shell pwsh --userconfig ./.npmrc
a następnie użyj pojedynczego polecenia skryptu npm:npm run start
źródło