| ||
auteur : Yan Verdavaine | ||
La grande majorité des API graphiques des divers OS ne sont absolument pas thread-safe. Le traitement IHM dans différents threads génère des accès concurrents et donc des crashs de l'application.
C'est pour cela que Qt oblige les traitements IHM dans le thread principal (celui exécutant le main() du programme). Attention, cette vérification n'est effectuée uniquement par des assert() en compilation debug. Si vous devez manipuler l'affichage par un thread, utilisez le système de connexion signal/slot |
| ||
auteur : Yan Verdavaine | ||
C'est très simple : un objet Qt appartient au thread qui l'a crée. Cela implique tout de même une règle importante :
un slot connecté de manière indirecte sera exécuté par l'eventloop du thread auquel l'objet appartient.
Warning : Il est possible de transférer l'appartenance d'un objet entre threads grâce à la méthode moveToThread. Mais ceci est à utiliser avec beaucoup de précaution.
|
| ||
auteur : Yan Verdavaine | ||
Qt fournit plusieurs possibilités pour manipuler des threads : * QtConcurrent : un ensemble d'algorithmes simplifiant énormément l'utilisation des threads. Il partage un pool de threads qui s'adaptera à la machine d'exécution. * QThread : c'est un classe qui interface un thread. Elle va créer, stopper, faire exécuter sa méthode run() et autres opération sur une thread. * QThreadPool : pour optimiser la création de threads, il est possible de manipuler un pool de thread avec QThreadPool . Ce pool de threads exécutera des classes héritant de QRunnable et réimplementant la méthode run(). |
| ||
auteur : Yan Verdavaine | ||
QThread est une interface simple permettant la création et manipulation d'un thread.
Elle ne peut être instanciée car la méthode run() est virtuelle pure.
Il faut donc créer une classe héritant de QThread et qui réimplémente la méthode run().
Voici les principales fonctionnalités à connaître :
Cette classe émet le signal started() lorsqu'un thread est lancé et finished()
lorsque le thread est terminé.
Il existe deux façons de l'utiliser :
Avant d'utiliser une QThread, voici quelques règles à bien comprendre :
Remarque : Qthread fournit aussi un slot nommé terminate() qui termine brutalement le thread. Cette fonction est à éviter le plus possible.
|
| ||
auteur : Yan Verdavaine | ||
Par défaut, la connexion entre thread est asynchrone car le slot sera exécuté dans
la thread qui possède l'objet receveur.
Pour cette raison, les paramètres du signal doivent être copiables. Ce qui implique quelques règles simples :
Il est possible d'utiliser ses propres classes. Pour cela il faut :
Contrairement aux slots, les signaux sont thread safe et peuvent donc être appelé par n'importe quel thread.
|
| ||
auteur : Yan Verdavaine | ||
Pour protéger des données partagées entre threads, Qt fournit la classe QMutex. Cette classe fourni
une base :
Afin de simplifier sa manipulation, Qt fournit la classe QMutexLocker basée sur le pattern RAII
qui permet de manipuler correctement le mutex et éviter certains problèmes (un thread qui essaye de bloquer deux fois un mutex, un mutex non débloqué suite à une exception,...). QMutexLocker va bloquer le mutex lors de sa création et le libérer lors de sa destruction.
Il permet aussi de libérer (unlock()) et de rebloquer (relock()) le mutex.
Lorsqu'une ressource est partagée entre plusieurs threads, ces threads ont le droit d'accéder parallèlement à la ressource uniquement si ils ne font que des accès en lecture. Ainsi, pour optimiser les accès, Qt fournit QReadWriteLock qui est un autre mutex beaucoup plus adapté. Contrairement à QMutex, QReadWriteLock va différencier les 'lock()' en lecture et écriture :
Mutex bloqué en lecture :
Mutex bloqué en écriture :
Comme QMutex, cette classe fournit une base :
De la même manière que QMutexLocker, Qt fournie deux classes qui simplifient la manipulation de ce mutex
|
| ||
auteur : Yan Verdavaine | ||
Pour diverse raison il peut être intéressant de mettre en pause l'exécution
d'un thread sur une durée déterminé.
Pour cela la classe QThread fournie plusieurs méthodes static :
|
Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.