J'ai un script PowerShell pour effectuer un traitement par lots sur un tas d'images et j'aimerais faire un traitement parallèle. Powershell semble avoir des 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 en 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 à foreach parallèle dans .net 4.
Quelque chose d'assez insensé comme:
foreach-parallel -threads 4 ($file in (Get-ChildItem $dir))
{
.. Do Work
}
Peut-être que je ferais mieux de passer à c # ...
multithreading
powershell
parallel-processing
Alan Jackson
la source
la source
receive-job (wait-job ($a = start-job { "heyo!" })); remove-job $a
ou$a = start-job { "heyo!" }; wait-job $a; receive-job $a; remove-job $a
Notez également que si vous appelezreceive-job
avant la fin du travail, vous risquez de ne rien obtenir du tout.(get-job $a).jobstateinfo.state;
Réponses:
Vous pouvez exécuter des travaux parallèles dans Powershell 2 à l'aide de travaux d'arrière-plan . Consultez Start-Job et les autres applets de commande de travail.
la source
Test-Path "\\$_\c$\Something"
je m'attendrais à ce qu'elle se développe$_
dans l'élément actuel. Cependant, ce n'est pas le cas. Au lieu de cela, il renvoie une valeur vide. Cela ne semble se produire qu'à partir de blocs de script. Si j'écris cette valeur immédiatement après le premier commentaire, cela semble fonctionner correctement.La réponse de Steve Townsend est correcte en théorie mais pas en pratique comme l'a souligné @likwid. Mon code révisé prend en compte la barrière du contexte de travail - rien ne franchit cette barrière par défaut! La
$_
variable automatique peut donc être utilisée dans la boucle mais ne peut pas être utilisée directement dans le bloc de script car elle se trouve dans un contexte distinct créé par le travail.Pour transmettre des variables du contexte parent au contexte enfant, utilisez le
-ArgumentList
paramètre onStart-Job
pour l'envoyer et utilisezparam
à l'intérieur du bloc de script pour le recevoir.(J'aime généralement fournir une référence à la documentation PowerShell comme preuve à l'appui mais, hélas, ma recherche a été infructueuse. Si vous savez où la séparation de contexte est documentée, postez un commentaire ici pour me le faire savoir!)
la source
Start-Job -FilePath script.ps1 -ArgumentList $_
http://gallery.technet.microsoft.com/scriptcenter/Invoke-Async-Allows-you-to-83b0c9f0
J'ai créé un invoke-async qui vous permet d'exécuter plusieurs blocs de script / cmdlets / fonctions en même temps. c'est idéal pour les petits travaux (scan de sous-réseau ou requête wmi contre des centaines de machines) car la surcharge de création d'un espace d'exécution par rapport au temps de démarrage du travail de démarrage est assez drastique. Il peut être utilisé comme ça.
avec scriptblock,
juste cmdlet / fonction
la source
Il y a tellement de réponses à cela ces jours-ci:
foreach-object -parallel
une alternative pour # 4Voici les flux de travail avec littéralement un foreach -parallel:
Ou un workflow avec un bloc parallèle:
Voici un exemple d'API avec des espaces d'exécution:
la source
Les travaux d'arrière-plan sont coûteux à configurer et ne sont pas réutilisables. PowerShell MVP Oisin Grehan a un bon exemple de multi-threading PowerShell.
(Le site du 25/10/2010 est en panne, mais accessible via l'archive Web).
J'ai utilisé un script Oisin adapté pour une utilisation dans une routine de chargement de données ici:
http://rsdd.codeplex.com/SourceControl/changeset/view/a6cd657ea2be#Invoke-RSDDThreaded.ps1
la source
Pour compléter les réponses précédentes, vous pouvez également utiliser
Wait-Job
pour attendre que toutes les tâches soient terminées:la source
Dans Powershell 7, vous pouvez utiliser ForEach-Object -Parallel
la source
Si vous utilisez le dernier PowerShell multiplateforme (que vous devriez d'ailleurs) https://github.com/powershell/powershell#get-powershell , vous pouvez en ajouter un
&
pour exécuter des scripts parallèles. (Utilisez;
pour 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 à utiliser
powershell
pour ses scripts (par défaut, il l'utilisecmd
sous Windows).Exécutez à partir du dossier racine du projet:
npm config set script-shell pwsh --userconfig ./.npmrc
puis utilisez une seule commande de script npm:npm run start
la source