La classe QThread fournit des threads indépendants de la plateforme.
Pour créer un thread, réalisez une sous-classe de QThread et réimplémentez sa fonction run(). Par exemple :
class MyThread : public QThread
{
Q_OBJECT
protected:
void run();
};
void MyThread::run()
{
...
}Maintenant, créez une instance de l'objet du thread et appelez QThread::start(). Notez que vous devez créer un objet de QApplication (ou de QCoreApplication) avant de pouvoir créer un QThread.
La fonction s'arrêtera immédiatement et le thread principal reprendra son cours. Le code qui apparaît dans la réimplémentation de run() sera exécuté dans un thread distinct.
La création de threads est expliquée plus en profondeur dans la documentation de QThread.
La classe QMutex fournit un accès à la sérialisation entre threads.
Le but de QMutex est de protéger un objet, une structure de données ou une section de code de sorte que qu'un seul thread puisse y accéder à un moment donné (ceci est similaire au mot-clé synchronized en Java). Il est généralement préférable d'utiliser un mutex avec un QMutexLocker il est ainsi plus facile d'assurer la cohérence du verrouillage et déverrouillage.
Par exemple, supposons qu'il existe une méthode qui renvoie un message à l'utilisateur sur deux lignes :
int number = 6;
void method1()
{
number *= 5;
number /= 4;
}
void method2()
{
number *= 3;
number /= 2;
}
Si ces deux méthodes sont appelées successivement, les événements suivants se produisent :
// method1()
number *= 5; // number est maintenant 30
number /= 4; // number est maintenant 7
// method2()
number *= 3; // number est maintenant 21
number /= 2; // number est maintenant 10Si ces deux méthodes sont appelées simultanément à partir de deux threads alors cela peut entraîner la séquence suivante :
// Thread 1 appelle method1()
number *= 5; // number est maintenant 30// Thread 2 appelle method2().
// Très probablement Thread 1 a été mis en sommeil par le système d'exploitation
// pour mettre le Thread 2 en route.
number *= 3; // number est maintenant 90
number /= 2; // number est maintenant 45
// Thread 1 finit son exécution.
number /= 4; // number est maintenant 11, au lieu de 10En ajoutant un mutex, nous devrions obtenir le résultat souhaité :
QMutex mutex;
int number = 6;
void method1()
{
mutex.lock();
number *= 5;
number /= 4;
mutex.unlock();
}
void method2()
{
mutex.lock();
number *= 3;
number /= 2;
mutex.unlock();
}Ici, un seul thread peut modifier number à un moment donné ce qui donne un résultat correct. Bien sûr, cet exemple est trivial, mais la méthode est applicable à chaque fois que l'on a besoin d'imposer une séquence particulière.
Quand vous appelez lock() dans un thread, les autres threads qui essayent d'appeler lock() sur le même mutex seront bloqués jusqu'à ce que le thread qui a le verrou appelle unlock(). Une alternative non bloquante de lock() est tryLock().