samedi 31 mars 2012

[Bash] Gestion de processus asynchrones

Lors d'une de mes formations "Unix et Programmation Shell", je me suis retrouvé devant une problématique d'un de mes élèves que je n'avais jamais rencontré auparavant. En effet son soucis était de pouvoir gérer correctement au sein d'un processus général le lancement de 4 processus en parallèle n'ayant pas les même temps d’exécution et de pouvoir continuer la suite de l’exécution générale tout en étant sûr que les 4 processus se soient terminés.

Je m'explique :
Soit le processus global contenant 4 processus indépendants :
- soit le processus 1 devant s’exécuter pendant 20 secondes
- soit le processus 2 devant s’exécuter pendant 30 secondes
- soit le processus 3 devant s’exécuter pendant 40 secondes
- soit le processus 4 devant s’exécuter pendant 10 secondes
Ces 4 processus sont lancés en même temps, et du fait que chaque processus ne va pas se terminer au même moment, il faut attendre que chaque script soit terminé pour continuer la suite d'un processus global

Pour résoudre ce problème, je vais créer un script qui va simuler ce temps d’exécution soit :

[ time.sh ]
#!/bin/bash
# JN - 2012
# script de simulation
# $1 : numéro du travail
# $2 : nombre d'itérations à effectuer (correspond à la durée d'exécution du processus secondes)

# Exemple : sh time.sh 2 30 - création du processus 2 pendant 30 secondes

i=0
touch Z$1
while [ $i -lt $2 ]
do
   echo `date` >> Z$1
   i=`expr $i + 1`
   sleep 1
done
echo $1" terminé !"

exit 0


Exécution des 4 processus en parallèle :

sh time.sh 1 20 & sh time.sh 2 30 & sh time.sh 3 40 & sh time.sh 4 10

NB : ces processus créént 4 fichiers Z1, Z2, Z3, Z4.
Pour ce faire nous allons utiliser à la fois la récupération des processus (PID) lancés en arrière plan soit la variable $! et la commande wait

Processus global :

[ global.sh ]
#!/bin/bash
# script global

# exécution des 4 processus 
sh time.sh 1 20 & var1="$!" & sh time.sh 2 10 & var2="$!" & sh time.sh 3 40 & var3="$!" & sh time.sh 4 30 & var4="$!"

# gestion de la synchronicité des processus
wait $var1 && wait $var2 && wait $var3 && wait $var4

# suite du processus général
echo "Tous les processus sont terminés ;) "


En ouvrant par exemple 4 fenêtres d'invite de commande pour  voir le déroulement des 4 processus (soit en utilisant par exemple la commande tail -f Z1, tail -f Z2, etc... ), et en lançant le processus général dans une 5ème fenêtre soit :


sh global.sh


 on obtient :




well done !!! ;)


Outil de capture vidéo utilisé :
http://doc.ubuntu-fr.org/capture