===== QMutex =====
La classe QMutex fournit un accès à la sérialisation entre threads. [[#Description détaillée|Plus d'informations...]]
==== Description détaillée ====
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 10
Si 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 10
En 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()]].
Voir aussi [[QMutexLocker]], [[QReadWriteLock]], [[QSemaphore]] et [[QWaitCondition]].
==== Type ====
=== RecursionMode-enum ===
''enum QMutex::RecursionMode''
^ Constante ^ Valeur ^ Description ^
| 'QMutex::Recursive' | 1 | Dans ce mode, un thread peut verrouiller le même mutex plusieurs fois mais le mutex ne sera déverrouillé que lorsque le déverrouillage [[#unlock()]] aura été appelé autant de fois que le verrouillage. |
| 'QMutex::NonRecursive' | 0 | Dans ce mode, un thread ne pourra verrouiller un mutex qu'une seule fois. |
Voir aussi [[#QMutex() - 1|QMutex()]].
==== Fonctions membres ====
=== QMutex() - 1 ===
''QMutex::QMutex ( [[#RecursionMode-enum|RecursionMode]] mode = NonRecursive )''
Construit un nouveau mutex. Le mutex est créé dans l'état déverrouillé.
Si le ''mode'' est [[#RecursionMode-enum|QMutex::Recursive]], un thread peut verrouiller le même mutex plusieurs fois et le mutex ne sera déverrouillé que lorsque le nombre d'appel à [[#unlock()]] sera le même que celui d'appel à [[#lock()]]. La valeur par défaut est [[#RecursionMode-enum|QMutex::NonRecursive]].
Voir aussi [[#lock()]] et [[#unlock()]].
=== ~QMutex() ===
''QMutex::~QMutex ()''
Détruit le mutex.
**Attention :** La destruction d'un mutex verrouillé peut engendrer un comportement inattendu de votre programme.
=== lock() ===
''void QMutex::lock ()''
Verrouille le mutex. Si un autre thread l'a déjà verrouillé alors cet appel sera bloquant jusqu'à ce que l'autre thread le déverrouille.
Il est possible d'appeler plusieurs fois cette fonction sur le même mutex si le mutex est [[#RecursionMode-enum|mutex récursif]]. Si le [[#RecursionMode-enum|mutex n'est pas récursif]], l'appel provoquera un verrou mortel (''dead-lock'').
Voir aussi [[#unlock()]].
=== tryLock() ===
''bool QMutex::tryLock ()''
Tente de verrouiller le mutex. Si le verrouillage est obtenu, cette fonction retournera true. Si un autre thread a verrouillé le mutex, cette fonction retournera immédiatement false.
Si le verrouillage est obtenu, le mutex devra être déverrouillé avec [[#unlock()]] avant qu'un autre thread ne puisse le verrouiller.
Il est possible d'appeler plusieurs fois cette fonction depuis le même thread sur un même mutex si celui-ci est [[#RecursionMode-enum|récursif]]. Sinon la fonction retournera ''false'' en cas de tentative de verrouillage récursif du mutex.
Voir aussi [[#lock()]] et [[#unlock()]].
=== tryLock() ===
''bool QMutex::tryLock ( int timeout )''
Ceci est une fonction membre surchargée.
Tente de verrouiller le mutex. La fonction renvoie true en cas de succès du verrouillage, false sinon. Si un autre thread a déjà verrouillé le mutex, la fonction attendra la disponibilité du mutex pendant au plus ''timeout'' millisecondes.
**Note :** Passer un nombre timeout négatif revient à appeler la fonction [[#lock()]], ce qui revient à dire que la fonction trylock() attendra indéfiniment que le mutex puisse être verrouillé.
Si le verrouillage est obtenu, le mutex devra être déverrouillé avec [[#unlock()]] avant qu'un autre thread ne puisse le verrouiller à nouveau.
Il est possible d'appeler plusieurs fois cette fonction depuis le même thread sur un même mutex si celui-ci est [[#RecursionMode-enum|récursif]]. Si le mutex n'est [[#RecursionMode-enum|pas récursif]], la fonction retournera ''false'' si elle tente de le verrouiller récursivement.
Voir aussi [[#lock()]] et [[#unlock()]].
=== unlock() ===
''void QMutex::unlock ()''
Si vous essayez de déverrouiller un mutex non préalablement verrouillé, votre programme adoptera un comportement inattendu.
Voir aussi [[#lock()]].
==== Remerciements ====
Merci à pour la traduction et à ainsi qu'à pour leur relecture !