Eu tenho um script do PowerShell para fazer um processamento em lote em várias imagens e gostaria de fazer um processamento paralelo. O Powershell parece ter algumas opções de processamento em segundo plano, como trabalho inicial, trabalho de espera, etc., mas o único bom recurso que encontrei para executar trabalhos paralelos foi escrever o texto de um script e executá-los ( PowerShell Multithreading )
Idealmente, eu gostaria de algo semelhante ao foreach paralelo no .net 4.
Algo bastante parecido com:
foreach-parallel -threads 4 ($file in (Get-ChildItem $dir))
{
.. Do Work
}
Talvez eu estivesse melhor apenas caindo para c # ...
multithreading
powershell
parallel-processing
Alan Jackson
fonte
fonte
receive-job (wait-job ($a = start-job { "heyo!" })); remove-job $a
ou$a = start-job { "heyo!" }; wait-job $a; receive-job $a; remove-job $a
Observe também que, se você ligarreceive-job
antes do término do trabalho, poderá obter nada.(get-job $a).jobstateinfo.state;
Respostas:
Você pode executar tarefas paralelas no Powershell 2 usando tarefas em segundo plano . Confira Iniciar trabalho e outros cmdlets do trabalho.
fonte
Test-Path "\\$_\c$\Something"
eu esperaria que ela se expandisse$_
para o item atual. No entanto, não. Em vez disso, ele retorna um valor vazio. Isso parece acontecer apenas dentro dos blocos de script. Se eu escrever esse valor imediatamente após o primeiro comentário, ele parece funcionar corretamente.A resposta de Steve Townsend está correta na teoria, mas não na prática, como apontou @likwid. Meu código revisado leva em consideração a barreira do contexto do trabalho - nada ultrapassa essa barreira por padrão! A
$_
variável automática pode, portanto, ser usada no loop, mas não pode ser usada diretamente no bloco de scripts, pois está dentro de um contexto separado criado pelo trabalho.Para passar variáveis do contexto pai para o contexto filho, use o
-ArgumentList
parâmetro onStart-Job
para enviá-lo e useparam
dentro do bloco de scripts para recebê-lo.(Geralmente, gosto de fornecer uma referência à documentação do PowerShell como evidência de suporte, mas, infelizmente, minha pesquisa foi infrutífera. Se você souber onde a separação de contexto está documentada, poste um comentário aqui para que eu saiba!)
fonte
Start-Job -FilePath script.ps1 -ArgumentList $_
http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0
Eu criei um invoke-async que permite executar vários blocos de script / cmdlets / funções ao mesmo tempo. isso é ótimo para trabalhos pequenos (varredura de sub-rede ou consulta wmi em centenas de máquinas), porque a sobrecarga para criar um espaço de execução versus o tempo de inicialização do trabalho inicial é bastante drástica. Pode ser usado assim.
com scriptblock,
apenas cmdlet / function
fonte
Existem muitas respostas para isso hoje em dia:
foreach-object -parallel
uma alternativa para o # 4Aqui estão os fluxos de trabalho com literalmente um foreach -parallel:
Ou um fluxo de trabalho com um bloco paralelo:
Aqui está um exemplo de API com espaços de execução:
fonte
Os trabalhos em segundo plano são caros de configurar e não são reutilizáveis. O MVP do PowerShell Oisin Grehan tem um bom exemplo de multiencadeamento do PowerShell.
(O site 25/10/2010 está inoperante, mas acessível através do Arquivo da Web).
Utilizamos o script Oisin adaptado para uso em uma rotina de carregamento de dados aqui:
http://rsdd.codeplex.com/SourceControl/changeset/view/a6cd657ea2be#Invoke-RSDDThreaded.ps1
fonte
Para concluir as respostas anteriores, você também pode
Wait-Job
aguardar a conclusão de todos os trabalhos:fonte
No Powershell 7, você pode usar o ForEach-Object -Parallel
fonte
Se você estiver usando o powershell de plataforma cruzada mais recente (que você deve btw) https://github.com/powershell/powershell#get-powershell , você poderá adicionar
&
scripts únicos para executar paralelos. (Use;
para executar sequencialmente)No meu caso, eu precisava executar scripts de 2 npm em paralelo:
npm run hotReload & npm run dev
Você também pode configurar o npm para usar
powershell
em seus scripts (por padrão, ele usacmd
no Windows).Execute da pasta raiz do projeto:
npm config set script-shell pwsh --userconfig ./.npmrc
e use o comando de script npm único:npm run start
fonte