[Resolu] Améliorer les performances

Améliorer les performances [Resolu] - Shell/Batch - Programmation

Marsh Posté le 04-08-2005 à 10:20:21    

Bonjour,
 
J ai un probleme de temps de traitement sur un programme en SHELL. Je travail chez uu FAI et pour la supervision temps reel on passe des interrogation sur des equipements réseau. Avec le dev de l'internet le nombre d'equipement à bcp augmenter.
 
Voici mon code.
 

Code :
  1. for Bas in $ListeBAS
  2. do
  3. $BIN""zjeton $Bas
  4. RetCode=$?
  5. if [ $RetCode == 0 ]
  6. then
  7.  $BIN""zjetonalloc $Bas get
  8.  expect -f $FichierExpBas $MachineHPOV $UserHPOV $Bas $UserBAS $PassBAS >$DON"Telnet_"$Bas".out.new"
  9.  RetCode=$?
  10.  $BIN""zjetonalloc $Bas free
  11. fi
  12. LineFile=`cat $DON"Telnet_"$Bas".out.new" | wc -l`
  13. print `date +"%d/%m/%Y_%H:%M:%S "`$Bas" "$RetCode" "$LineFile
  14.     echo "tuyau\t"$Bas"\t"$MachineHPOV"\t"`date +"%d/%m/%Y_%H:%M:%S "`"\t"$RetCode"\t"$LineFile>> $FichierLog
  15. if [ $RetCode != "0" ]
  16. then
  17.  RedoBas=$Bas" "$RedoBas
  18.  DateFichier=`date +"%d%m%Y_%H%M%S"`
  19.  cp $DON"Telnet_"$Bas".out.new" $DON"Telnet_"$Bas".out."$DateFichier
  20. else
  21.  cat $DON"Telnet_"$Bas".out.new" | tr -sd "\r" "" > $DON"Telnet_"$Bas".out"
  22. fi
  23. sleep 5
  24. done


 
Le principe c est que j execute un script sur des equipements mais je les fait un par un. J aimerai les faire en parallele. Chaque script expect prend environ 15 % de ressource processur, serait il possible d en faire fonctionner 4 par 4 ?
Est ce possible ? Comment aborder la chose ?
 
Merci


Message édité par td-rat le 18-08-2005 à 14:44:36
Reply

Marsh Posté le 04-08-2005 à 10:20:21   

Reply

Marsh Posté le 04-08-2005 à 13:07:12    

Tu peux le faire "à la bourrin" en comptant le nombre de processes expect actuellement actifs au début de ta boucle for/done. S'il est inférieur à 4, tu continues la boucle, sinon tu attends X secondes et tu check à nouveau.
Qque chose du genre:
 

[...]
for Bas in $ListeBAS
do
 while true
 do
  MaxProc=4
  SleepTimer=10
  NbProc=`ps -ef | grep expect | grep -v grep | wc -l`
  [ $NbProc -lt $MaxProc ] && break || sleep $SleepTimer
 done
$BIN""zjeton $Bas
RetCode=$?
[...]


 
Par contre il faudra dans ton script lancer expect en background (& ).


---------------
Institutions européennes: Ensemble d'outils dont le but est de transformer une grande quantité d'argent en merde. Cette merde est utilisée pour créer de nouveaux fonctionnaires. L'argent restant payant des externes pour faire leur travail.
Reply

Marsh Posté le 04-08-2005 à 13:41:19    

Ouai c est realisable, et de meme avant de quitter mon programme principale il faut que tout les process fils soit terminé car les traitement qui arrivent par la suite en peuvent pas commencer avant que tout les expect soient terminer.
 
Pour faire cette gestion de processus ? je fais tout avec  
ps -ef | grep PID >> proc.txt et j analyse ?

Reply

Marsh Posté le 04-08-2005 à 13:55:22    

Si j utilise "ps -l" ca va aussi ?

Reply

Marsh Posté le 04-08-2005 à 16:00:28    

"wait" sans argument attend que tous les sous-process aient termine. Si tu peux utiliser ca, c'est mieux que l'attente active proposee par Deadlock. Une autre approche serait d'utiliser la commande "jobs" pour conter le nombre de processes en background, et d'en lancer un nouveau des que tu en a moins de 4.

Reply

Marsh Posté le 04-08-2005 à 16:21:15    

D'où le "à la bourrin" dans mon post ;)


---------------
Institutions européennes: Ensemble d'outils dont le but est de transformer une grande quantité d'argent en merde. Cette merde est utilisée pour créer de nouveaux fonctionnaires. L'argent restant payant des externes pour faire leur travail.
Reply

Marsh Posté le 04-08-2005 à 16:44:05    

matafan a écrit :

"wait" sans argument attend que tous les sous-process aient termine. Si tu peux utiliser ca, c'est mieux que l'attente active proposee par Deadlock. Une autre approche serait d'utiliser la commande "jobs" pour conter le nombre de processes en background, et d'en lancer un nouveau des que tu en a moins de 4.


 
Merci pour ton aide.
 
As tu des exemples par hasard?

Reply

Marsh Posté le 04-08-2005 à 20:32:01    

En fait en y repensant j'ai une meilleure solution. Cree une fonction, appelons-la "doit", qui fait la tache que tu veux lancer en paralele. Cree une fonction "sigchld" qui compte le d'instances de la fonction doit (jobs | grep doit | wc -l), et qui lance un nouveau doit (doit & ) si ce nombre est plus petit que 4 (donc if [ `jobs | grep doit | wc -l` -lt 4 ]). Ensuite enregistre "sigchld" en temps que signal handler pour le signal SIGCHLD (trap doit SIGCHLD). Puis lance 4 fois doit en background (doit &; doit &; doit &; doit & ). Le tour est joue, tu aura en permanence 4 instances de ta fonction doit. Tu peux evidemment passer un argument a doit (le nom de la machine a laquelle elle doit se connecter par exemple) de sorte qu'elle fasse quelque chose de different a chaque fois. Quand tu as lancer le dernier doit, desenregistre sigchld.

Reply

Marsh Posté le 04-08-2005 à 21:50:05    

Bon j'ai fais un petit essaie et c'est bizarre, je ne recois jamais de SIGCHLD... Donc finalement je propose une solution de ce type, ou "doit" est la fonction que tu veux lancer en paralele :

#!/bin/sh
 
arg=0
 
function doit {
         sec=$(( RANDOM * 10 / 32768 + 10 ))
         echo "-> doit $1: sleep $sec"
         sleep $sec
         echo "<- doit $1: sleep $sec"
}
 
function respawn {
         while [ `jobs -r | grep doit | wc -l` -lt $1 ]
         do
                 (( arg += 1 ))
                 doit $arg &
         done
}
 
while :;
do
         respawn 4
         sleep 1
done


Ici la fonction respawn se charge de relancer le nombre de doit qu'il faut pour arriver a 4.

Reply

Marsh Posté le 05-08-2005 à 10:16:49    

Ok merci, c est ce que j avais fait

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed