Exécution de plusieurs processus d'arrière-plan simultanés, puis attendez qu'ils se terminent tous, sous Windows


14

Quelqu'un sait-il s'il existe un script cmd qui le fait et / ou un outil de ligne de commande prêt pour le travail?


Cela pourrait endommager vos données!
Santosh Kumar

8
@Santosh: que voulez-vous dire par "peut nuire à vos données"? Dans mon cas spécifique, les tâches d'arrière-plan traiteraient leurs propres ensembles de données indépendants. Aucun risque de modifications simultanées.
Sergio

1
Du côté de l'API Win32, je pense que WaitForMultipleObjects avec bWaitAll = TRUE ferait le travail. Il ne serait pas difficile d'écrire un programme qui supprime simplement les programmes donnés dans un fichier d'entrée, s'il n'y a pas de réponses satisfaisantes.
user1686

1
@grawity: oui, je prévois de le faire si rien ne vient (et de poster le code ici), mais voyons si je peux éviter de réinventer la roue :)
Sergio

Réinventer la roue est une bonne chose si les roues existantes sont carrées ...
user1686

Réponses:


10

Créez les trois fichiers batch ci-dessous. Main.bat lance 1.bat et 2.bat

1.bat et 2.bat écrivent des fichiers temporaires pour lesquels main.bat vérifie. Pendant que 1.bat et 2.bat fonctionnent, main.bat signale que le traitement est toujours en cours. Lorsque vous appuyez sur Entrée dans la fenêtre ouverte de 1.bat ou 2.bat, le fichier temporaire est supprimé et le programme se ferme. Cela simule l'arrêt du traitement pour ce fichier .bat. Si vous procédez ainsi pour 1 et 2.bat, main.bat vous signale que le traitement est terminé pour ces processus. Vous pouvez faire 1.bat et 2.bat faire ce que vous voulez, tant que vous effacez le fichier temporaire lorsque vous avez terminé. À ce stade, main.bat peut également faire tout ce que vous voulez.

1.bat

echo %time% > 1.tmp
pause
del 1.tmp
exit 

2.bat

echo %time% > 2.tmp
pause
del 2.tmp
exit

main.bat

@echo off
start "1" 1.bat
start "2" 2.bat
    @ping -n 1 127.0.0.1 > nul
:loop
@echo Processing......
if not exist *.tmp goto :next
    @ping -n 5 127.0.0.1 > nul
goto loop
:next
@echo Done Processing!

Cela fait, je peux vous dire que cette approche n'est pas aussi difficile qu'il n'y paraît. De plus, il est facile à entretenir - pour étendre et ajouter de la logique, et facile à former quelqu'un d'autre pour le maintenir. Habituellement, ces choses prennent leur propre vie ...
RobW

Je suis content de cette solution.
user1068446

Pourriez-vous développer la commande @ping? Je ne comprends pas pourquoi vous choisissez de faire cela et ce qu'est la 127.0.0.1.
Joe

6

Assez simple, à condition que les processus n'aient pas besoin d'entrée ou de sortie standard. Depuis la ligne de commande ou dans un fichier batch:

process1 | process2 | process3 | process4

Cela exécutera les quatre processus simultanément et ne reviendra pas tant qu'ils ne seront pas tous terminés. (Exception possible: si un processus ferme explicitement la sortie standard, il peut être traité comme s'il s'était arrêté. Mais c'est inhabituel, très peu de processus le font.)

Je ne sais pas exactement combien de processus vous pouvez lancer simultanément de cette façon. J'en ai essayé jusqu'à dix.


Uhm, ce que j'obtiens, c'est que tous les processus sont en effet démarrés en même temps, mais process3 reste en attente jusqu'à ce que process4 soit terminé, process2 reste en attente jusqu'à ce que process3 se termine, et ainsi de suite. Cela vient d'ailleurs de l'invite de commande Windows classique.
Sergio

@Sergio: Que voulez-vous dire par "gardé en attente"?
Harry Johnston

1

La seule façon de procéder consiste à démarrer des fichiers de commandes séparés (voir start /?) qui exécutent la tâche individuelle et à écrire un fichier texte à la fin. Ensuite, vous vérifiez périodiquement si les fichiers texte ont été créés.


0

Vous pouvez consulter la cmdlet Powershell Start-Job. Cela devrait vous permettre de le faire. Plus ici Powershell est le shell de choix de Microsoft. Il est beaucoup plus puissant que les scripts cmd et investit bien votre temps


Cela n'attend pas qu'ils se terminent tous?
Tamara Wijsman

Cela peut certainement dépendre de la façon dont vous l'écrivez. Vous pouvez interroger les travaux démarrés pour voir s'ils ont terminé et quitter votre script une fois qu'ils l'ont fait. Le code de cette page traite toute une liste de travaux, trois à la fois et attend leur sortie.
uSlackr

Uhm, je n'avais jamais rien fait auparavant avec Powershell. J'ai essayé de changer l'exemple pour exécuter des processus arbitraires et d'attendre qu'ils se terminent et après environ 30 minutes et 100 recherches sur M $ technet, j'ai abandonné. Je suis désolé si j'ai blessé quelqu'un mais Powershell est de la merde. C'est plus facile à faire en C (ce qui, je pense, est révélateur ...) Merci quand même, je parie que quelqu'un trouvera toujours cela utile.
Sergio

S'il y a une chose que Powershell n'est pas, c'est de la merde et vous ne blesserez pas mes sentiments si vous ne l'utilisez pas. Vous ne l'apprendrez cependant pas en 30 minutes de recherche.
uSlackr

1
PowerShell n'est pas de la merde, c'est juste un langage de programmation complet qu'il faut apprendre, au lieu d'une syntaxe traditionnelle de type sh. Je me souviens avoir ressenti exactement la même chose à propos de Perl, Python, Tcl, C # et tous les autres langages que j'ai essayé d'apprendre "pour le lulz" sans aucune utilisation réelle pour le moment. (Quand j'ai vraiment eu besoin d' eux, cependant, cela s'est passé assez facilement.)
user1686

0

Ou vous pouvez utiliser ceci: http://www.out-web.net/?p=167

Je l'ai fait, cela fonctionne, mais il arrive parfois que le PID du processus terminé soit immédiatement réutilisé par un autre processus Windows qui vient de démarrer, et cela rend la détection de la fin de votre processus dangereuse / erronée.


2
Veuillez résumer ce que dit ce lien. Si la page descend, cette réponse ne sera pas utile.
Kevin Panko

Il semble trop tard.
Robert Massa

0

Je cherchais également une tâche similaire. L'objectif était d'exécuter plusieurs commandes en parallèle et d'extraire la sortie (stdout & error) de tous les processus parallèles. Attendez ensuite que tous les processus parallèles se terminent et exécutez une autre commande. Voici un exemple de code pour le fichier BAT, qui peut être exécuté dans CMD:

( start "" /B cmd /c ping localhost -n 6 ^>nul timeout /t 5 /nobreak start "" /B /D "C:\users\username\Desktop" cmd /c dir ^> dr.txt ^2^>^&^1 start "" /B cmd /c ping localhost -n 11 ^>nul timeout /t 10 /nobreak ) | pause Echo waited timeout /t 12 /nobreak

Toutes les instructions à l'intérieur ()sont exécutées en premier, attendez qu'elles se terminent, puis les deux dernières lignes sont exécutées. Toutes les commandes commençant par startsont exécutées simultanément.

Ces liens sont utiles: /programming//a/43762349/9689416 et https://ss64.com/nt/start.html

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.