Tengo un script de PowerShell para hacer un procesamiento por lotes en un montón 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 recurso bueno que encontré para hacer un trabajo paralelo fue escribir el texto de un script y ejecutarlo ( PowerShell Multithreading )
Idealmente, me gustaría algo similar a foreach paralelo en .net 4.
Algo bastante parecido a:
foreach-parallel -threads 4 ($file in (Get-ChildItem $dir))
{
.. Do Work
}
Tal vez estaría mejor simplemente bajando a c # ...
multithreading
powershell
parallel-processing
Alan Jackson
fuente
fuente
receive-job (wait-job ($a = start-job { "heyo!" })); remove-job $a
o$a = start-job { "heyo!" }; wait-job $a; receive-job $a; remove-job $a
Tenga en cuenta también que si llamareceive-job
antes de que finalice el trabajo, es posible que no obtenga nada.(get-job $a).jobstateinfo.state;
Respuestas:
Puede ejecutar trabajos paralelos en Powershell 2 utilizando trabajos en segundo plano . Consulte Start-Job y los otros cmdlets de trabajo.
fuente
Test-Path "\\$_\c$\Something"
esperaría que se expanda$_
al elemento actual. Sin embargo, no lo hace. En su lugar, devuelve un valor vacío. Esto solo parece suceder desde dentro de los bloques de script. Si escribo ese valor inmediatamente después del primer comentario, parece que funciona correctamente.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 laboral: ¡ nada cruza esa barrera por defecto! Por lo tanto, la
$_
variable automática se puede usar en el bucle 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 primario al contexto secundario, use el
-ArgumentList
parámetro onStart-Job
para enviarlo y useparam
dentro del bloque de script para recibirlo.(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 sabe dónde está documentada la separación de contexto, ¡publique un comentario aquí para avisarme!)
fuente
Start-Job -FilePath script.ps1 -ArgumentList $_
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 (escaneo de subred o consulta wmi en cientos de máquinas) porque la sobrecarga para crear un espacio de ejecución frente al tiempo de inicio del trabajo de inicio es bastante drástica. Se puede usar así.
con scriptblock,
solo cmdlet / function
fuente
Hay tantas respuestas a esto en estos días:
foreach-object -parallel
alternativa para # 4Aquí hay flujos de trabajo con literalmente un foreach-paralelo:
O un flujo de trabajo con un bloque paralelo:
Aquí hay un ejemplo de API con espacios de ejecución:
fuente
Los trabajos en segundo plano son caros de configurar y no son reutilizables. PowerShell MVP Oisin Grehan tiene un buen ejemplo de PowerShell multi-threading.
(25/10/2010 el sitio está inactivo, pero accesible a través del Archivo web).
He usado el script Oisin adaptado para usar en una rutina de carga de datos aquí:
http://rsdd.codeplex.com/SourceControl/changeset/view/a6cd657ea2be#Invoke-RSDDThreaded.ps1
fuente
Para completar las respuestas anteriores, también puede usar
Wait-Job
para esperar a que se completen todos los trabajos:fuente
En Powershell 7 puede usar ForEach-Object -Parallel
fuente
Si está utilizando el último PowerShell multiplataforma (que debería ser por cierto) https://github.com/powershell/powershell#get-powershell , puede agregar un solo
&
para ejecutar scripts paralelos. (Utilizar;
para correr secuencialmente)En mi caso, necesitaba ejecutar scripts de 2 npm en paralelo:
npm run hotReload & npm run dev
También puede configurar npm para usarlo
powershell
en sus scripts (por defecto lo usacmd
en Windows).Ejecute desde la carpeta raíz del proyecto:
npm config set script-shell pwsh --userconfig ./.npmrc
y luego use el comando de script npm único:npm run start
fuente