Bonjour à tous,
Je précise que je n'ai pas une expérience très étoffée de l'usage des threads.
Dans le cadre d'un projet, j'ai développé une application avec wx-widget faisant du calcul intensif et proposant une IHM de monitoring.
Je dispose dans l'application de deux wxthreads:
- Le thread principal dans lequel je crée la fenêtre de suivi du calcul.
- Un thread de calcul.
Ma fenetre de suivi, instance de la classe Monitoframe dérivée de wxFrame est référencée par un pointeur encaspulé dans un Singleton.
Mon thread de calcul modifie les valeurs de certains champs des widgets de ma fenêtre (des wxStaticText et une wxGauge). Le problème est que mon thread de calcul appelle les fonctions de mon instance de monitoframe pour modifier l'affichage de l'avancement sans synchronisation.
En fait mon code ressemble à ça:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| // Initialisation de la fenêtre de monitoring
bool application::OnInit()
{
wxInitAllImageHandlers();
MonitoFrame* frame = new monitoFrame(0L); // On crée la fenêtre.
...
SingletonParamsGlobals::getInstance()->lancerThreadCalcul(m, argc, argv); // On lance le thread de calcul,
...
}
void SingletonParamsGlobals::lancerThreadCalcul(Commande* _m, int argc , char **argv)
{
t = new Tlaunch(_m, argc, argv);
t->Create();
t->Run();
} |
Le code de lancement du thread de calcul ressemble à ça:
1 2 3 4 5 6 7 8 9
| void* Entry(){
if( TestDestroy() )
return NULL;
resultat = m->launch(_argc, _argv);
exit(0);
}
int getResultat(){
return resultat;
} |
Dans le code de mon thread de calcul, je fais régulièrement appel à des méthodes de la classe MonitoFrame, par exemple:
SingletonParamsGlobals::getInstance()->getFenetrePrincipale()->setAvancement(0);
Lorsque je fais des appels "trop rapprochés" aux fonctions de Monitoframe, j'ai quelque fois un plantage violent. D'où mes questions:
Pourquoi ai-je ce comportement ? un champ d'un wxStaticText est-il modifié par le thread de calcul alors que le thread principal gérant l'affichage essaie d'accéder à sa valeur pour l'afficher ?
D'ailleurs, pourquoi le "repaint" de ma fenêtre est-il automatique lorsque par exemple, je modifie la valeur d'un wxStaticText ? Je pense que le problème vient de là, le thread principal demandant l'affichage d'un champ dont je modifie potentiellement la valeur de manière concurente au travers du thread principal.
Avez-vous des liens vers des tutoriaux expliquant comme bien synchronizer la modification des valeurs d'une IHM depuis un thread de calcul ou simplement de petits conseils à me donner. Je suis un peu perdu.
Cordialement,
Benoît.
Partager