136 votes

Powershell peut-il exécuter des commandes en parallèle ?

J'ai un script powershell pour effectuer un traitement par lots sur un groupe d'images et j'aimerais effectuer un traitement parallèle. Powershell semble avoir quelques options de traitement en arrière-plan telles que start-job, wait-job, etc, mais la seule bonne ressource que j'ai trouvée pour effectuer un travail parallèle était d'écrire le texte d'un script et de les exécuter ( PowerShell Multithreading )

Idéalement, j'aimerais quelque chose qui ressemble à la méthode foreach parallèle de .net 4.

Quelque chose d'assez banal comme :

foreach-parallel -threads 4 ($file in (Get-ChildItem $dir))
{
   .. Do Work
}

Peut-être que je ferais mieux de descendre en C#...

0 votes

tl;dr : 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 Notez également que si vous appelez receive-job avant que le travail soit terminé, vous pourriez ne rien recevoir du tout.

0 votes

Aussi (get-job $a).jobstateinfo.state;

6voto

Thomas Points 7717

Pour compléter les réponses précédentes, vous pouvez également utiliser Wait-Job pour attendre que tous les travaux soient terminés :

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

4voto

izharsa Points 43

Dans Powershell 7, vous pouvez utiliser Pour chaque objet -Parallèle

$Message = "Output:"
Get-ChildItem $dir | ForEach-Object -Parallel {
    "$using:Message $_"
} -ThrottleLimit 4

3voto

JerryGoyal Points 9110

Si vous utilisez le dernier powershell multiplateforme (ce que vous devriez faire) https://github.com/powershell/powershell#get-powershell vous pouvez ajouter des & pour exécuter des scripts parallèles. (Utilisez ; à exécuter séquentiellement)

Dans mon cas, j'avais besoin d'exécuter 2 scripts npm en parallèle : npm run hotReload & npm run dev


Vous pouvez également configurer npm pour utiliser powershell pour ses scripts (par défaut il utilise cmd sur Windows).

Exécuter à partir du dossier racine du projet : npm config set script-shell pwsh --userconfig ./.npmrc et ensuite utiliser la commande unique npm script : npm run start

"start":"npm run hotReload & npm run dev"

2voto

Chris Points 514

Cette question a reçu une réponse complète. Je veux juste poster cette méthode que j'ai créée sur la base de Powershell-Jobs comme référence.

Les travaux sont transmis sous la forme d'une liste de blocs de script. Ils peuvent être paramétrés. La sortie des jobs est codée en couleur et préfixée avec un index de job (comme dans un vs-build-process, car cela sera utilisé dans un build). Peut être utilisé pour démarrer plusieurs serveurs à la fois ou pour exécuter des étapes de construction en parallèle, etc

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."
    }
}

sortie de l'échantillon :

sample output

0 votes

Comment se fait-il que la 7ème ligne montre un bleu i symbole. Le script ne perd-il pas toutes les informations de couleur de la sortie des scripts de travail sous-jacents ?

0 votes

Si je me souviens bien, je n'ai pas touché au script après avoir généré la sortie. donc je suppose que la couleur n'est pas enlevée. malheureusement pwsh n'est pas très cohérent quand il s'agit des couleurs de la console, donc je ne suis pas du tout sûr.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X