The QMutex, QReadWriteLock, QSemaphore, and QWaitCondition classes provide means to synchronize threads. While the main idea with threads is that they should be as concurrent as possible, there are points where threads must stop and wait for other threads. For example, if two threads try to access the same global variable simultaneously, the results are usually undefined.
QMutex provides a mutually exclusive lock, or mutex. At most one thread can hold the mutex at any time. If a thread tries to acquire the mutex while the mutex is already locked, the thread will be put to sleep until the thread that currently holds the mutex unlocks it. Mutexes are often used to protect accesses to shared data (i.e., data that can be accessed from multiple threads simultaneously). In the Reentrancy and Thread-Safety section below, we will use it to make a class thread-safe.
QReadWriteLock is similar to QMutex, except that it distinguishes between "read" and "write" access to shared data and allows multiple readers to access the data simultaneously. Using QReadWriteLock instead of QMutex when it is possible can make multithreaded programs more concurrent.
QSemaphore is a generalization of QMutex that protects a certain number of identical resources. In contrast, a mutex protects exactly one resource. The Semaphores example shows a typical application of semaphores: synchronizing access to a circular buffer between a producer and a consumer.
QWaitCondition allows a thread to wake up other threads when some condition has been met. One or many threads can block waiting for a QWaitCondition to set a condition with wakeOne() or wakeAll(). Use wakeOne() to wake one randomly selected event or wakeAll() to wake them all. The Wait Conditions example shows how to solve the producer-consumer problem using QWaitCondition instead of QSemaphore.
Note that Qt's synchronization classes rely on the use of properly aligned pointers. For instance, you cannot use packed classes with MSVC.