Bonjour à tous,
J'ai débuté Qt il y a de ça 3 semaines. J'ai plutôt un background Windows (C++, C#, Javascript, etc..).
Je dois réaliser une application qui deviendra par la suite un deamon et/ou un service windows. Toutefois, pour le moment ce qui fonctionne le mieux pour débugger c'est la console évidemment.
Ce service ou deamon devra communiquer en tout temps avec un port série, donc il doit fonctionner 24h/24h, à moin d'être arrêter manuellement.
Si j'étais en C++ Windows, je crois que j'implémenterais une classe (disons nommer Worker) et c'est elle qui ferait tout le travail. Donc, elle aurait que 3 fonctions publiques soit Init, Start et Stop. Elle démarrerait un thread qui lorsqu'on appel la fonction Init. Les fonction Start et Stop basculerait le thread soit en mode actif ou pause. Et le plus important c'est que dans son destructeur elle s'assure que le thread est bel et bien ARRÊTER correctement.
Jusqu'ici j'ai réussi assez facilement à créer le projet, implémenter la classe, démarer le thread et tout...Cependant, pour la question d'arrêter le thread correctement, alors là c'est n'importe quoi
Sur Windows, une application console peut être fermée de plusieurs façon, dont :
- Du bouton X de la fenêtre
- CTRL+C
- ALT+F4
- ... et quelques autres façon
J'ai tenté d'intercepté ces évements avec le mécanisme de QT (QApplicationCore::aboutToQuitApp), mais elle n'est jamais déclanché ! La seul façon que j'ai réussi c'est en interceptant les signal (SIGINT, SIGTERM, SIGBREAK, etc...) :
Disons que par la suite que j'ai voulu ARRÊTER correctement mon thread, c'est à dire :
- Lui indiquer qu'il doit arrêter
- Attendre qu'il ait terminé
- Et finalement fermer l'application console
Voici ce que j'ai tenté jusqu'ici : Ne soyez dur avec le code (scope, privé, publique, bool au lieu de QWaitCondition etc...), j'ai fait beaucoup de test et j'ai raccourci beaucoup pour simplifer et que ça soit pas trop long pour mettre ici.
Avec les commentaires dans le code vous comprendrez sûrement plus que si j'explique. En gros l'application semble décéder et ammener avec elle le worker thread, sans que j'ai de possibilité de syncroniser cet arrêt correctement.
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 #include <QCoreApplication> #include <QThread> #include <QDebug> #include <csignal> class WorkerThread : public QThread { public: explicit WorkerThread (QObject *parent = 0) :m_bStopThread(false) { } private: void run() { // Le thread ne doit JAMAIS arrêter, à moins qu'on lui // demande explicitement via m_bStopThread while (!m_bStopThread) { qDebug() << "Depuis le worker thread: " << currentThreadId(); QThread::msleep(1000); } return; // Ce break-point n'est JAMAIS atteint ! } public : volatile bool m_bStopThread; public Q_SLOTS: void aboutToQuitApp() { m_bStopThread = true; // Ce break-point n'est JAMAIS atteint ! } }; struct CleanExit { static WorkerThread* pWorkerThread; CleanExit(WorkerThread* _pWorkerThread) { CleanExit::pWorkerThread = _pWorkerThread; signal(SIGINT, &CleanExit::exitQt); signal(SIGTERM, &CleanExit::exitQt); signal(SIGBREAK, &CleanExit::exitQt) ; } static void exitQt(int sig) { // Une fois le SIGINT intercepté, le debugger se // rend ici, mais il disparait lorsqu'on jump sur // la ligne suivante. Comme s'il plantait (QtCreator et VS 2012) ! pWorkerThread->m_bStopThread = true; pWorkerThread->wait(); QCoreApplication::exit(0); } }; WorkerThread* CleanExit::pWorkerThread = NULL; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); WorkerThread wk; CleanExit cleanExit(&wk); QObject::connect(&wk, SIGNAL(finished()), &a, SLOT(quit())); QObject::connect(&a, SIGNAL(aboutToQuit()), &wk, SLOT(aboutToQuitApp())); qDebug() <<"Démarrage du worker thread : " << QThread::currentThreadId(); // Démarrage du Thread wk.start(); // Attendre que le thread soit bel et bien arrêter ! wk.wait(); return a.quit(); }
Bref, j'ai passé un trop grand nombre d'heure à essayer de faire fonctionner tout cela et je suis découragé. J'espère que quelqu'un ici aura des suggestions ou des solutions.
Merci à tous.
Partager