Powershell 명령어를 병렬로 실행할 수 있습니까?
다수의 이미지를 일괄 처리하는 powershell 스크립트를 가지고 있으며 병렬 처리를 하고 싶습니다.Powershell에는 시작 작업, 대기 작업 등의 백그라운드 처리 옵션이 몇 가지 있는 것 같습니다만, 병렬 작업을 실시하기 위한 유일한 리소스는 스크립트 텍스트를 작성하고 실행하는 것이었습니다(PowerShell 멀티스레딩).
이상적으로는 .net 4의 평행 포어치 같은 것을 원합니다.
뭔가 좀 아닌 것 같죠?
foreach-parallel -threads 4 ($file in (Get-ChildItem $dir))
{
.. Do Work
}
그냥 c#으로 내려가는 게 나을 것 같은데...
백그라운드 작업을 사용하여 Powershell 2에서 병렬 작업을 실행할 수 있습니다.Start-Job 및 기타 작업 cmdlet을 확인합니다.
# Loop through the server list
Get-Content "ServerList.txt" | %{
# Define what each job does
$ScriptBlock = {
param($pipelinePassIn)
Test-Path "\\$pipelinePassIn\c`$\Something"
Start-Sleep 60
}
# Execute the jobs in parallel
Start-Job $ScriptBlock -ArgumentList $_
}
Get-Job
# Wait for it all to complete
While (Get-Job -State "Running")
{
Start-Sleep 10
}
# Getting the information back from the jobs
Get-Job | Receive-Job
스티브 타운센드의 대답은 이론적으로는 맞지만 실제론 @likwid가 지적한 것처럼 정확하지 않다.개정된 코드에는 직무 컨텍스트 장벽이 고려되어 있습니다.기본적으로 그 장벽을 넘는 것은 없습니다.오토매틱$_
따라서 변수는 루프에서 사용할 수 있지만 작업에 의해 작성된 별도의 컨텍스트 내에 있기 때문에 스크립트블록 내에서 직접 사용할 수 없습니다.
하려면 , 「」를합니다.-ArgumentList
의 Start-Job
쓰다param
스크립트 블록 내에서 수신합니다.
cls
# Send in two root directory names, one that exists and one that does not.
# Should then get a "True" and a "False" result out the end.
"temp", "foo" | %{
$ScriptBlock = {
# accept the loop variable across the job-context barrier
param($name)
# Show the loop variable has made it through!
Write-Host "[processing '$name' inside the job]"
# Execute a command
Test-Path "\$name"
# Just wait for a bit...
Start-Sleep 5
}
# Show the loop variable here is correct
Write-Host "processing $_..."
# pass the loop variable across the job-context barrier
Start-Job $ScriptBlock -ArgumentList $_
}
# Wait for all to complete
While (Get-Job -State "Running") { Start-Sleep 2 }
# Display output from all jobs
Get-Job | Receive-Job
# Cleanup
Remove-Job *
(일반적으로 PowerShell 문서를 참고 자료로 제공하고 싶지만 안타깝게도 검색 결과가 없었습니다.콘텍스트 분리가 문서화되어 있는 장소를 알고 있는 경우는, 여기에 코멘트를 달아 주세요.
오늘날에는 이에 대한 해답이 매우 많습니다.
- 작업(또는 PS 6/7의 스레드 작업 또는 PS 5의 모듈)
- 개시 프로세스
- 워크플로우(PS 5 한정)
- powershell api와 다른 runspace를 사용합니다.
- 여러 컴퓨터가 있는 invoke 명령어(모두 localhost일 수 있음)(admin이어야 함)
- ISE의 여러 세션(런스페이스) 탭 또는 리모트 powershell ISE 탭
- 에는 Powershell 7이 되어 있습니다.
foreach-object -parallel
#4의
powershell 5.1에서 start-threadjob을 사용한다.기대했던 대로 작동했으면 좋겠지만, 그렇지 않습니다.
# test-netconnection has a miserably long timeout
echo yahoo.com facebook.com |
start-threadjob { test-netconnection $input } | receive-job -wait -auto
WARNING: Name resolution of yahoo.com microsoft.com facebook.com failed
이런 식으로 작동합니다.powershell 7에 필적하는, 그다지 훌륭하지 않고 포어치 오브젝트도 아니지만, 그럴 것이다.
echo yahoo.com facebook.com |
% { $_ | start-threadjob { test-netconnection $input } } |
receive-job -wait -auto | ft -a
ComputerName RemotePort RemoteAddress PingSucceeded PingReplyDetails (RTT) TcpTestS
ucceeded
------------ ---------- ------------- ------------- ---------------------- --------
facebook.com 0 31.13.71.36 True 17 ms False
yahoo.com 0 98.137.11.163 True 97 ms False
다음은 말 그대로 전치 병렬이 포함된 워크플로우입니다.
workflow work {
foreach -parallel ($i in 1..3) {
sleep 5
"$i done"
}
}
work
3 done
1 done
2 done
또는 병렬 블록이 있는 워크플로우:
function sleepfor($time) { sleep $time; "sleepfor $time done"}
workflow work {
parallel {
sleepfor 3
sleepfor 2
sleepfor 1
}
'hi'
}
work
sleepfor 1 done
sleepfor 2 done
sleepfor 3 done
hi
다음은 runspaces를 사용하는 api의 예입니다.
$a = [PowerShell]::Create().AddScript{sleep 5;'a done'}
$b = [PowerShell]::Create().AddScript{sleep 5;'b done'}
$c = [PowerShell]::Create().AddScript{sleep 5;'c done'}
$r1,$r2,$r3 = ($a,$b,$c).begininvoke() # run in background
$a.EndInvoke($r1); $b.EndInvoke($r2); $c.EndInvoke($r3) # wait
($a,$b,$c).streams.error # check for errors
($a,$b,$c).dispose() # clean
a done
b done
c done
Powershell 7에서는 각 객체에 대해 병렬을 사용할 수 있습니다.
$Message = "Output:"
Get-ChildItem $dir | ForEach-Object -Parallel {
"$using:Message $_"
} -ThrottleLimit 4
http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0
invoke-clocks/clocks/clocks를 동시에 실행할 수 있는 invoke-clocks를 만들었습니다.이는 작은 작업(기동 작업의 시작 시간과 비교하여 런스페이스 생성에 대한 오버헤드가 상당히 크기 때문에 100대의 머신에 대해 스캔 또는 WMI 쿼리를 실행)에 적합합니다.이렇게 쓸 수 있어요.
스크립트 블록 포함,
$sb = [scriptblock] {param($system) gwmi win32_operatingsystem -ComputerName $system | select csname,caption}
$servers = Get-Content servers.txt
$rtn = Invoke-Async -Set $server -SetParam system -ScriptBlock $sb
cmdlet/기능만
$servers = Get-Content servers.txt
$rtn = Invoke-Async -Set $servers -SetParam computername -Params @{count=1} -Cmdlet Test-Connection -ThreadCount 50
백그라운드 작업은 설정 비용이 많이 들고 재사용할 수 없습니다.PowerShell MVP Oisin Grehan은 PowerShell 멀티스레딩의 좋은 예입니다.
(2010년 10월 25일 사이트가 다운되었지만 웹 아카이브를 통해 액세스할 수 있습니다).
데이터 로딩 루틴에서 사용하기 위해 Oisin 스크립트를 사용했습니다.
http://rsdd.codeplex.com/SourceControl/changeset/view/a6cd657ea2be#Invoke-RSDDThreaded.ps1
이전 답변을 완료하려면 다음을 사용할 수도 있습니다.Wait-Job
모든 작업이 완료될 때까지 기다립니다.
For ($i=1; $i -le 3; $i++) {
$ScriptBlock = {
Param (
[string] [Parameter(Mandatory=$true)] $increment
)
Write-Host $increment
}
Start-Job $ScriptBlock -ArgumentList $i
}
Get-Job | Wait-Job | Receive-Job
최신 크로스 플랫폼 powershell을 사용하는 경우(이것이 필요) https://github.com/powershell/powershell#get-powershell, 를 1 개 추가할 수 있습니다.&
병렬 스크립트를 실행합니다.;
순차적으로 실행)
제 경우 2개의 npm 스크립트를 동시에 실행해야 했습니다.npm run hotReload & npm run dev
npm을 설정하여powershell
(디폴트에서는,cmd
를 참조해 주세요).
프로젝트 루트 폴더에서 실행:npm config set script-shell pwsh --userconfig ./.npmrc
그런 다음 단일 npm 스크립트명령어를 사용합니다.npm run start
"start":"npm run hotReload & npm run dev"
이것은 충분히 해결되었습니다.참고용으로 Powershell-Jobs를 기반으로 만든 이 메서드를 게시하고 싶습니다.
작업은 스크립트 블록 목록으로 전달됩니다.파라미터화할 수 있습니다.작업의 출력은 색상으로 구분되어 작업 인덱스로 프리픽스가 붙습니다(빌드에서 사용되는 것과 마찬가지로 vs-build 프로세스에서도 마찬가지).한 번에 여러 서버를 시작하거나 빌드 단계를 병렬로 실행할 때 사용할 수 있습니다.
function Start-Parallel {
param(
[ScriptBlock[]]
[Parameter(Position = 0)]
$ScriptBlock,
[Object[]]
[Alias("arguments")]
$parameters
)
$jobs = $ScriptBlock | ForEach-Object { Start-Job -ScriptBlock $_ -ArgumentList $parameters }
$colors = "Blue", "Red", "Cyan", "Green", "Magenta"
$colorCount = $colors.Length
try {
while (($jobs | Where-Object { $_.State -ieq "running" } | Measure-Object).Count -gt 0) {
$jobs | ForEach-Object { $i = 1 } {
$fgColor = $colors[($i - 1) % $colorCount]
$out = $_ | Receive-Job
$out = $out -split [System.Environment]::NewLine
$out | ForEach-Object {
Write-Host "$i> "-NoNewline -ForegroundColor $fgColor
Write-Host $_
}
$i++
}
}
} finally {
Write-Host "Stopping Parallel Jobs ..." -NoNewline
$jobs | Stop-Job
$jobs | Remove-Job -Force
Write-Host " done."
}
}
출력 예:
PowerShell 7.0 Preview 3에는 새로운 솔루션이 내장되어 있습니다.각 오브젝트의 PowerShell 병렬 기능
다음과 같은 작업을 수행할 수 있습니다.
Get-ChildItem $dir | ForEach-Object -Parallel {
.. Do Work
$_ # this will be your file
}-ThrottleLimit 4
언급URL : https://stackoverflow.com/questions/4016451/can-powershell-run-commands-in-parallel
'bestsource' 카테고리의 다른 글
iOS info.plist 파일 내의 문자열을 현지화하려면 어떻게 해야 합니까? (0) | 2023.04.09 |
---|---|
프리태그에 텍스트를 줄 바꿈하려면 어떻게 해야 합니까? (0) | 2023.04.09 |
지정된 커밋을 포함하는 브랜치를 나열하려면 어떻게 해야 합니까? (0) | 2023.04.09 |
iOS 앱 'The application cannot verify(애플리케이션을 검증할 수 없습니다)'가 한 기기에만 표시됨 (0) | 2023.04.09 |
stringByAppendingPathComponent를 사용할 수 없습니다. (0) | 2023.04.09 |