Question.
Tu fait des std::cout dans deux threads différent?
Si oui, il faut savoir que le cout n'est pas thread safe.
Question.
Tu fait des std::cout dans deux threads différent?
Si oui, il faut savoir que le cout n'est pas thread safe.
Ok voila du code. Y'a pas tout, et je vous rappelle que ce programme est juste un exercice pour me familiariser avec les threads. De plus, j'ai changé des trucs pour garder un peu d'intimité. En gros, m'emmerder pas sur la synthaxe, les sécurités, les noms des variables, etc...
Ceci concerne mon thread :
Voilà ce qui concerne mon interface ( j'ai pas mis le mutex ) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 MyThread :: MyThread(QObject *parent):QThread(parent) { stopped=false; ConfOk=false; step = 0; qs = ""; readTime = new QTime(); readTime->start(); } void MyThread::run() { //QMutexLocker locker(&readMutex); readMutex.lock(); fonctionConfigurationCommunication(...)//configure la comm avec le périphérique if(InitialisationCorrecteCommunication()) { cout<<"Connexion bien établie\n"; readMutex.unlock(); while(stopped==false) { readMutex.lock(); readTime->restart(); MaStructureDeDonnees MesDonnees=DemanderDonnees(); emit donneesLues(MesDonnees); cout << "Temps lecture = " << (QString::number(readTime->elapsed())).toStdString() << endl; readMutex.unlock(); } readMutex.lock(); FermerLaCommunication(); cout<<"Connexion terminée\n"; readMutex.unlock(); } else {cout<<"Problème lors de l'initialisation !!!\n"; readMutex.unlock();} }
Je crois avoir bien compris l'histoire des méthodes ThreadSafe, et je suis un peu initié aux caprices des processeurs. Cependant cet exemple devrait fonctionner correctement (selon moi). Les petites erreurs dans la sortie remettent en cause ma compréhension du phénomène, c'est pour ca que je te pose ces questions. Mais c'est plus de la curiosité qu'un problème. J'aime bien etre sûr d'avoir compris, c'est tout.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 MaWindow::MaWindow(QWidget *parent) : QWidget(parent) { table = new QTableWidget(34,2,this); start = new QPushButton("Start Thread"); stop = new QPushButton("Stop Thread"); QVBoxLayout *vl = new QVBoxLayout(this); QObject::connect(start,SIGNAL(clicked()),this,SLOT(threadStart())); QObject::connect(stop,SIGNAL(clicked()),this,SLOT(threadStop())); vl->addWidget(table); vl->addWidget(start); vl->addWidget(stop); displayTime = new QTime(0,0,0,0); displayTime->start(); } void MaWindow::threadStart() { t = new MyThread; qRegisterMetaType<MaStructureDeDonnees>("MaStructureDeDonnees"); cout<<"t = "<<t<<"\n"; QObject::connect(t,SIGNAL(donneesLues(MaStructureDeDonnees)),this,SLOT(afficheDonnees(MaStructureDeDonnees))); cout<<"thread cree\n"; t->start(); } void MaWindow::threadStop() { if(t->isRunning) { t->threadStop(); while(t->isRunning()) ; } } void MaWindow::afficheDonnees(MaStructureDeDonnees MesDonnees) { displayTime->restart(); tableItem = new QTableWidgetItem(QString::number(MesDonnees.valeur1)); this->table->setItem(1,1,tableItem); tableItem = new QTableWidgetItem(QString::number(MesDonnees.valeur2)); this->table->setItem(2,1,tableItem); ... cout << "Temps affichage = " << (QString::number(displayTime->elapsed())).toStdString() << endl; }
Tu remarqueras que j'utilise les QMutex à la façon "old school". Si ça fait pas de différences pour la machine avec le QMutexLocker, ça en fait une pour ma perception. J'aime pas laisser la machine faire ça pour moi.
Bonne lecture, et merci
G.
Edit : Par rapport à la remarque de MonGaulois : merci, j'avais la flemme d'aller vérifier. Cependant, l'utilisation du QMutex devrait le rendre safe non ?
up up
Ce que tu pourrais faire est d'avoir un slot dans ton main windows qui affiche sur la console et un signal dans la thread et la mainwindows pour envoyer le message à afficher
Puis tu fait les connecte qui te faut (en connection Qt::QueuedConnection , ca blindera peut être l'ordre d'affichage)
Absolument pas. Un mutex n'est pas associé à une ressource particulière. C'est pour ça que j'en ai fait une classe dans mon exemple... page précédente...
Edit: c'était en réponse à Gulish, pas à Mongaulois
Edit 2: et j'avais raté ça:
Tu remarqueras que j'utilise les QMutex à la façon "old school". Si ça fait pas de différences pour la machine avec le QMutexLocker, ça en fait une pour ma perception. J'aime pas laisser la machine faire ça pour moi.
Va lire un peu plus sur le RAII, et lis un peu (plus?) sur les deadlocks et leur conséquence, et ça te convaincra d'utiliser le plus possible un QMutexLocker (notez bien que je ne dis pas "toujours")
Ok Ok, j'ai compris. De toute façon, la console ne sera plus là à terme, c'est juste pour faire mes tests. Je pensais que le QMutex bloquait l'accès à toutes les ressources situées entre le lock et le unlock, et que le std::cout "se viderait complètement" avant d'être réappelé.
Enfin voilà, merci pour tout. Longue vie à développer.com.
Je reviendrai vous embêter bientôt, promis
G.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager