Saltar al contenido

¿Cómo ejecutar una función de PowerShell varias veces en paralelo?

Esta es el arreglo más acertada que encomtrarás brindar, pero obsérvala pausadamente y analiza si se adapta a tu trabajo.

Solución:

No es necesario actualizar para esto. Defina un bloque de script y use Start-Job para ejecutar el bloque de script tantas veces como sea necesario. Ejemplo:

$cmd = 
  param($a, $b)
  Write-Host $a $b


$foo = "foo"

1..5 | ForEach-Object 
  Start-Job -ScriptBlock $cmd -ArgumentList $_, $foo

El bloque de script toma 2 parámetros $a y $b que son pasados ​​por el -ArgumentList opción. En el ejemplo anterior, las asignaciones son $_$a y $foo$b. $foo es solo un ejemplo para un configurable, pero static parámetro.

Correr Get-Job | Remove-Job en algún momento para eliminar los trabajos terminados de la cola (o Get-Job | % Receive-Job $_.Id; Remove-Job $_.Id si desea recuperar la salida).

Aquí hay un scriptblock falso rápido con el propósito de probar:

$Code = 
    param ($init)
    $start = Get-Date
    (1..30) 

Este scriptblock se puede pasar a Start-Jobcon por ejemplo 3 parámetros (10, 15, 35)

$jobs = @()
(10,15,35) | %  $jobs += Start-Job -ArgumentList $_ -ScriptBlock $Code 

Wait-Job -Job $jobs | Out-Null
Receive-Job -Job $jobs

Esto crea 3 trabajos, asígnalos a la $jobs variable, los ejecuta en paralelo y luego espera a que terminen estos 3 trabajos y recupera los resultados:

Counted from 10 until 40 in 00:00:30.0147167.
Counted from 15 until 45 in 00:00:30.0057163.
Counted from 35 until 65 in 00:00:30.0067163.

Esto no tardó 90 segundos en ejecutarse, solo 30.

Una de las partes difíciles es proporcionar -Argumentlist para Start-Jobe incluir un param() bloque dentro de ScriptBlock. De lo contrario, el scriptblock nunca verá sus valores.

Puede usar una alternativa que puede ser más rápida que invocar trabajos si la función no es de ejecución prolongada. El subproceso máximo es 25 y solo invoco esta función 10 veces, por lo que espero que mi tiempo de ejecución total sea de 5 segundos. Puede envolver Medida-Comando alrededor de la declaración ‘resultados =’ para ver las estadísticas.

Ejemplo:

$ScriptBlock = 
    Param ( [int]$RunNumber )
    Start-Sleep -Seconds 5   
    Return $RunNumber

$runNumbers = @(1..10)
$MaxThreads = 25
$runspacePool = [RunspaceFactory ]::CreateRunspacePool(1, $MaxThreads)
$runspacePool.Open()
$pipeLines = foreach($num in $runNumbers)
    $pipeline = [powershell]::Create()
    $pipeline.RunspacePool = $runspacePool
    $pipeline.AddScript($ScriptBlock)    
#obtain results as they come.
$results =  foreach($pipeline in $pipeLines)
    $pipeline.EndInvoke($pipeline.AsyncResult )

#cleanup code.
$pipeLines | %  $_.Dispose()
$pipeLines = $null
if ( $runspacePool )  $runspacePool.Close()
#your results
$results

No se te olvide mostrar esta sección si te valió la pena.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *