Bonjour,
Je souhaite avoir un process qui se déroule en plusieurs étapes. Les
étapes se succèdent les unes aux autres, chacune dans son thread
secondaire. Pour ce faire j'essaie d'adopter une architecture simple
basée sur 3 threads :
1. Thread d'attente du signal de lancement : THR_WAIT
Ce thread est lancé dès l'ouverture de la fenêtre. Il attend la
réception d'un signal pour lancer le thread secondaire d'exécution puis
un autre thread secondaire qui attend la fin du thread d’exécution
2. Thread d'exécution de la fonction liée à l'étape : THR_RUN
Durant l'exécution la variable etape_suivante est fixée.
3. Thread de surveillance de la fin d’exécution du thread d'exécution :
THR_END
Ce thread renvoi un signal au thread d'attente pour lancer l'étape
suivante et se termine
Tout se déroule pour le mieux jusqu'à ce que l'on doit utiliser la
fonction trace. La doc indique que la fonction trace est similaire à la
fonction info. Je crée une fonction 'thrp_trace' qui exécutera la
fonction trace depuis le thread principal.
Tout va pour le mieux, c-à-d que les étapes se succèdent normalement
jusqu'au moment où ... on agit sur la fenêtre de trace (déplacement,
redimensionnement, ...) lors du débogage.
Symptôme : Le thread d'éxécution semble en pause ! Les windgets
(libellés, ...) et trace traduisent la fin d'activité de l'étape.
Mieux : Le thread de surveillance ne détecte même pas la mort du thread
d'exécution pour renvoyer un signal au thread d'attente de signal ! J'ai
créé une fenêtre soeur avec un bouton pour afficher l'état courant des 3
threads. Le thread d'exécution est annoncé toujours en cours pourtant
aucun signe de vie !
Un peu de code
Initialisation du projet
ThreadMode(threadSectionCritique)
Initialisation de la fenêtre
OuvreSoeur(FEN_Threads)
ThreadExécute("P1_THR_WAIT",threadNormal+threadAttendDémarrage,COL_Process.thr_waitP1)
COL_Process.geEtapeSuivante = EP1Etapes.RETOUR_IDDLE
Initialisation
ThreadEnvoieSignal("P1_THR_WAIT")
Bouton de lancement
COL_Process.geEtapeSuivante = EP1Etapes.ETAPE_01
ThreadEnvoieSignal("P1_THR_WAIT")
PROCEDURE thr_waitP1()
BOUCLE
ThreadAttendSignal(Infini)
SI PAS ThreadEtat("P1_THR_END") = threadInexistant ALORS
ThreadAttend("P1_THR_END",Infini)
FIN
COL_Process.thrp_next()
FIN
PROCEDURE thrp_next()
SI COL_Process.geEtapeSuivante = EP1Etapes.IDDLE ALORS
RETOUR
SI PAS ThreadEtat("P1_THR_RUN") = threadInexistant ALORS
RETOUR
FIN
SELON COL_Process.geEtapeSuivante
CAS EP1Etapes.ETAPE_01 :
COL_Process.geEtapeEnCours = EP1Etapes.ETAPE_02
COL_Process.geEtapeSuivante = EP1Etapes.RETOUR_IDDLE
ThreadExécute("P1_THR_RUN",threadNormal+threadAttendDémarrage,COL_Process.etape1)
CAS EP1Etapes.ETAPE_02 :
COL_Process.geEtapeEnCours = EP1Etapes.ETAPE_02
COL_Process.geEtapeSuivante = EP1Etapes.RETOUR_IDDLE
ThreadExécute("P1_THR_RUN",threadNormal+threadAttendDémarrage,COL_Process.etape2)
CAS EP1Etapes.ETAPE_03 :
COL_Process.geEtapeEnCours = EP1Etapes.ETAPE_03
COL_Process.geEtapeSuivante = EP1Etapes.RETOUR_IDDLE
ThreadExécute("P1_THR_RUN",threadNormal+threadAttendDémarrage,COL_Process.etape3)
CAS EP1Etapes.ETAPE_04 :
COL_Process.geEtapeEnCours = EP1Etapes.ETAPE_04
COL_Process.geEtapeSuivante = EP1Etapes.RETOUR_IDDLE
ThreadExécute("P1_THR_RUN",threadNormal+threadAttendDémarrage,COL_Process.etape4)
CAS EP1Etapes.ETAPE_05 :
COL_Process.geEtapeEnCours = EP1Etapes.ETAPE_05
COL_Process.geEtapeSuivante = EP1Etapes.RETOUR_IDDLE
ThreadExécute("P1_THR_RUN",threadNormal+threadAttendDémarrage,COL_Process.etape5)
CAS EP1Etapes.RETOUR_IDDLE :
COL_Process.geEtapeEnCours = EP1Etapes.RETOUR_IDDLE
COL_Process.geEtapeSuivante = EP1Etapes.IDDLE
ThreadExécute("P1_THR_RUN",threadNormal+threadAttendDémarrage,COL_Process.etape_retourIddle)
AUTRE CAS
FIN
ThreadExécute("P1_THR_END",threadNormal+threadAttendDémarrage,COL_Process.thr_endP1)
PROCEDURE PRIVÉE thr_endP1()
ThreadAttend("P1_THR_RUN", Infini)
ThreadEnvoieSignal("P1_THR_WAIT")
Exemple de code d'une étape
PROCEDURE PRIVÉE etape2()
ExécuteThreadPrincipal(thrp_etape2)
infos (libellé, ...
thrp_trace("Fin étape 2")
COL_Process.geEtapeSuivante = EP1Etapes.ETAPE_03
ThreadPause(100)
PROCEDURE thrp_trace(sMsg est une chaîne)
ExécuteThreadPrincipal(_trace,sMsg)
PROCEDURE PRIVÉE _trace(sMsg est une chaîne)
SectionCritiqueDébut()
TraceDébut(trFenêtre)
Trace(sMsg)
SectionCritiqueFin()
PROCEDURE PRIVÉE thrp_etape2()
SectionCritiqueDébut()
FEN_principale.LIB_Proc_etape = "Etape 2"
SectionCritiqueFin()
Merci pour votre aide