voici un petit tutoriel pour aborder une notion sympathique en programmation : le script réentrant.
ça sert partout où
- il faut exécuter des choses en parallèles : on fait un script qui fait plusieurs run de lui-même.
- il faut exécuter des choses compliquées avec runas ou runaswait : on fait un script qui s'appelle lui même avec runaswait. C'est illustré ici [EX] Exécuter un script en tant qu'administrateur mais sans nommer le concept, ce qui est dommage quand on fait une recherche...
Le script réentrant permet de ne pas avoir à gérer 2(ou plus) codes sources ( un pour le père, un pour chaque fils ), mais un seul code source, ce qui permet de le maintenir cohérent plus facilement.
Exemples où ça peut servir : [..] Sons simultanés dans autoit ?
[..] Problème avec RunAS ... débutant
LA REENTRANCE , C'EST QUOI ?
Imaginons qu'on veut un programme qui affiche 2 msgbox, mais en même temps. On va créer un 1er script qui se contente d'afficher le contenu de CMDLINE[1] dans une msgbox:
- Appelons ce script mamsgbox.au3
Code : Tout sélectionner
msgbox(16,"COUCOU",$CMDLINE[1])
- Appelons ce script principal.au3
Code : Tout sélectionner
run("mamsgbox.exe 1er_message")
run("mamsgbox.exe 2me_message")
MsgBox(0,"FINNNN","fin du père")
On a donc bien maintenant un programme qui joue deux msgbox en même temps... Sauf que le programme père ne sait pas quand les 2 programmes "mamsgbox" se terminent : le script principal arrive tout de suite vers sa propre fin et basta.. c'est gênant si on veut coder quelque chose de plus compliqué, par exemple avec un traitement à ne continuer que lorsque tous les traitements fils se sont terminés.
Voici donc un programme père plus élaboré, qui attend la fin des fils : c'est facile, il suffit de récupérer le N° de process de chaque fils au moment du RUN, et d'attendre que ces processus aient disparus pour continuer le déroulement du père.
- script pere avec attente des fils:
Code : Tout sélectionner
$PID1=run("mamsgbox.exe 1er_message")
$PID2=run("mamsgbox.exe 2me_message")
; boucle d'attente de la fin des fils.
$FILS_ACTIFS=0
Do
$FILS_ACTIFS=0
If ProcessExists($PID1) Then $FILS_ACTIFS=1
If ProcessExists($PID2) Then $FILS_ACTIFS=1
; pour pas faire un 100% CPU avec la boucle...
If $FILS_ACTIFS Then sleep(100)
Until Not($FILS_ACTIFS)
MsgBox(0,"FINNNN","fin du père")
Maintenant, on va aborder le coeur même du principe de la réentrance : Plutôt que d'écrire deux scripts différents, pourquoi ne pas écrire qu'un seul script ?
Si le script est appelé sans argument, c'est que c'est l'utilisateur qui l'a appelé. Si le script est appelé avec un argument, alors c'est que c'est le script père qui l'a appelé . Autrement dit, on va avoir un script séparé en 2 parties : père et fils.
En fait, le script s'appelle lui même avec run, mais comme on a prévu un traitement différent suivant la présence ou non d'un argument, le script se comporte à la fois comme le père et le fils ( ça va, vous suivez ? )
Code : Tout sélectionner
; La partie "FILS" du script
If $CMDLINE[0] = 1 Then
;
; ICI, ce qu'on fait en tant que FILS
;
else
;
; ICI, ce qu'on fait en tant que PERE
;
endif
► Afficher le texte
Voila, on touche au but. maintenant, si on veut pouvoir gérer un nombre de scripts fils plus important, il faut passer aux tableaux ( imaginez la gueule du script au dessus avec 10 msgbox à lancer en même temps... ).
ça permet aussi de faire une boucle pour lancer tous les fils, puis une 2eme boucle qui va scanner la présence de tous les fils lancé
► Afficher le texte
Je traite la partie "fils" avant la partie "père" : A l'usage, c'est mieux de faire comme ça que l'inverse : le code du fils est généralement assez court, et il vaut mieux le mettre devant.
Il reste un problème potentiel : Si on en a besoin, comment les fils vont remonter des informations à la partie "père" du script ?
La seule solution consiste à passer par un fichier.
Chaque fils connait son propre PID ( @AutoitPID ). Si le fils écrit des résultats dans un fichier du genre @scriptname & "_" & @AutoitPID , le père saura retrouver ce fichier dès que le fils aura terminé son exécution...