multithreading - txt - ¿Pueden los comandos de ejecución Powershell en paralelo?
powershell tutorial (4)
Tengo un script de PowerShell para hacer un procesamiento por lotes en un grupo de imágenes y me gustaría hacer un procesamiento paralelo. Powershell parece tener algunas opciones de procesamiento en segundo plano como start-job, wait-job, etc., pero el único buen recurso que encontré para hacer trabajo en paralelo fue escribir el texto de un script y ejecutarlo ( PowerShell Multithreading )
Idealmente, me gustaría algo parecido al foreach paralelo en .net 4.
Algo bastante parecido a esto:
foreach-parallel -threads 4 ($file in (Get-ChildItem $dir))
{
.. Do Work
}
Tal vez sería mejor bajar a c # ...
La respuesta de Steve Townsend es correcta en teoría, pero no en la práctica, como señaló @likwid. Mi código revisado tiene en cuenta la barrera del contexto de trabajo: ¡ nada cruza esa barrera de forma predeterminada! La variable $_
automática se puede utilizar así en el ciclo, pero no se puede usar directamente dentro del bloque de script porque está dentro de un contexto separado creado por el trabajo.
Para pasar variables del contexto principal al contexto hijo, use el parámetro -ArgumentList
en Start-Job
para enviarlo y use param
dentro del bloque de scripts para recibirlo.
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 *
(En general, me gusta proporcionar una referencia a la documentación de PowerShell como evidencia de apoyo, pero, por desgracia, mi búsqueda ha sido infructuosa. Si usted sabe dónde está documentada la separación del contexto, ¡envíe un comentario aquí para informarme!)
Los trabajos de fondos son costosos de configurar y no son reutilizables. La MVP de PowerShell Oisin Grehan tiene un buen ejemplo de multithreading de PowerShell http://www.nivot.org/2009/01/22/CTP3TheRunspaceFactoryAndPowerShellAccelerators.aspx
(25/10/2010 el sitio está caído):
Utilicé una secuencia de comandos Oisin adaptada para su uso en una rutina de carga de datos aquí:
http://rsdd.codeplex.com/SourceControl/changeset/view/a6cd657ea2be#Invoke-RSDDThreaded.ps1
Puede ejecutar trabajos paralelos en Powershell 2 utilizando trabajos en segundo plano . Consulte Start-Job y los otros cmdlets de trabajo.
# 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
http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0
Creé un invoke-async que le permite ejecutar múltiples bloques de script / cmdlets / funciones al mismo tiempo. esto es ideal para trabajos pequeños (exploración de subred o wmi contra 100 de máquinas) porque la sobrecarga para crear un espacio de ejecución frente al tiempo de inicio de la tarea inicial es bastante drástico. Se puede usar así.
con scriptblock,
$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
solo cmdlet / función
$servers = Get-Content servers.txt
$rtn = Invoke-Async -Set $servers -SetParam computername -Params @{count=1} -Cmdlet Test-Connection -ThreadCount 50