10 votes

Shell Shell : exécuter un lot de N commandes en parallèle, attendre que toutes se terminent, exécuter les N suivantes.

Tâche : exécuter des blocs composés de 3 à 5 commandes (en parallèle/en arrière-plan). Exemple de bloc :

dd if=/dev/urandom of=/mnt/1/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/2/x bs=1024 count=1024000000 &
dd if=/dev/urandom of=/mnt/3/x bs=1024 count=1024000000 &

Quand c'est fait, le bloc suivant doit s'exécuter. Je suppose que cela peut être fait via des fichiers de verrouillage :

task1.sh :

real_task1 real_param1 ; rm /var/lock/myscript/task1.lock

task2.sh :

real_task2 real_param1 ; rm /var/lock/myscript/task2.lock

...

taskgen.sh :

# loop
 # while directory isn't empty - wait...
 gen_tasks.pl # build task files from some queue
 for i in 1 2 3; do touch /var/lock/myscript/task$i.lock ; done
 ./task1.sh &
 ./task2.sh &
 ./task3.sh &
 # if task1.sh doesn't exits then exit, else loop waits for files to be deleted

On peut trouver un certain nombre de méthodes pour vérifier si le répertoire est vide ici Je ne sais pas lequel utiliser ;

Question : une meilleure façon de mettre cela en œuvre ?

P.S. Méthode de rapport d'état possible :

 command && report_good_state.sh taskid ;  report_state_done.sh taskid; rm /var/lock/myscript/taskN.lock

9voto

sjors miltenburg Points 694

Peut-être une variation sur ce sujet ?

while true
do
  ./task1.sh&
  pid1=$!
  ./task2.sh&
  pid2=$!
  ./task3.sh&
  pid3=$!
  wait $pid1
  wait $pid2
  wait $pid3
done

9voto

RyanBrady Points 1903

C'est exactement ce que gnu parallel est conçu pour, donc je vous recommande fortement de l'utiliser. En particulier, regardez si vous pouvez l'exécuter comme un sémaphore :

for i in {1..4}
do
  echo running $i
  sem -j3 df dd if=/dev/urandom of=/mnt/$i/x bs=1024 count=1024000000 ";" echo done
done
# sem --wait waits until all jobs are done.
sem --wait

5voto

Selah Points 2445

Avez-vous une raison particulière de ne pas utiliser quelque chose comme GNU parallel ? Si vous devez utiliser bash, envisagez alors des méthodes comme celles décrites dans cet article de blog (l'attente et les tuyaux nommés sont utiles ici).

3voto

ˈoʊ sɪks Points 237

"wait" attend que toutes les tâches d'arrière-plan soient terminées. Exemple :

dormir 30 & sleep 40 & sleep 120 & attendre

Il attend que toutes les commandes soient terminées, c'est-à-dire au moins 120 secondes pour cet exemple.

J'espère que cela vous aidera.

0voto

Tim Bunce Points 101

Nous avons essayé d'utiliser le Utilitaire GNU sem comme décrit par Phil Hollenback ci-dessus, mais j'ai trouvé qu'il était trop lourd (300+ instances paralysaient la machine). J'ai cherché des outils similaires pour implémenter un sémaphore de comptage léger mais je n'ai rien trouvé de convenable.

J'en ai donc implémenté un moi-même en utilisant flock, il s'appelle sémaphorique .

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X