Doc: Generalize problems and solutions of mutex use
These apply to other locks too, not just mutexes. Move from "Thread Basics" to "Synchronizing Threads" Change-Id: I6d7051cb225a8c836fb591a28b65d3de8fab4083 Reviewed-by: Olivier Goffart <ogoffart@woboq.com> Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>bb10
parent
2524cafc8e
commit
370b642092
|
|
@ -246,26 +246,6 @@
|
|||
}
|
||||
\endcode
|
||||
|
||||
What happens if one thread does not unlock a mutex? The result can be a
|
||||
frozen application. In the example above, an exception might be thrown and
|
||||
\c{mutex.unlock()} will never be reached. To prevent problems like this,
|
||||
QMutexLocker should be used.
|
||||
|
||||
\code
|
||||
void Worker::work()
|
||||
{
|
||||
QMutexLocker locker(&mutex); // Locks the mutex and unlocks when locker exits the scope
|
||||
doWork();
|
||||
}
|
||||
\endcode
|
||||
|
||||
This looks easy, but mutexes introduce a new class of problems: deadlocks.
|
||||
A deadlock happens when a thread waits for a mutex to become unlocked, but
|
||||
the mutex remains locked because the owning thread is waiting for the first
|
||||
thread to unlock it. The result is a frozen application. Mutexes can be
|
||||
used to make a method thread safe. Most Qt methods aren't thread safe
|
||||
because there is always a performance penalty when using mutexes.
|
||||
|
||||
\section2 Dealing with Asynchronous Execution
|
||||
|
||||
One way to obtain a worker thread's result is by waiting for the thread
|
||||
|
|
|
|||
|
|
@ -338,6 +338,30 @@
|
|||
aligned pointers. For instance, you cannot use packed classes with
|
||||
MSVC.
|
||||
|
||||
These synchronization classes can be used to make a method thread safe.
|
||||
However, doing so incurs a performance penalty, which is why most Qt methods
|
||||
are not made thread safe.
|
||||
|
||||
\section2 Risks
|
||||
|
||||
If a thread locks a resource but does not unlock it, the application may
|
||||
freeze because the resource will become permanently unavailable to other threads.
|
||||
This can happen, for example, if a an exception is thrown and forces the current
|
||||
function to return without releasing its lock.
|
||||
|
||||
Another similar scenario is a \e{deadlock}. For example, suppose that
|
||||
thread A is waiting for thread B to unlock a resource. If thread B is also
|
||||
waiting for thread A to unlock a different resource, then both threads will
|
||||
end up waiting forever, so the application will freeze.
|
||||
|
||||
\section2 Convenience classes
|
||||
|
||||
QMutexLocker, QReadLocker and QWriteLocker are convenience classes that make it
|
||||
easier to use QMutex and QReadWriteLock. They lock a resource when they are
|
||||
constructed, and automatically unlock it when they are destroyed. They are
|
||||
designed to simplify code that use QMutex and QReadWriteLocker, thus reducing
|
||||
the chances that a resource becomes permanently locked by accident.
|
||||
|
||||
\section1 High-Level Event Queues
|
||||
|
||||
Qt's \l{The Event System}{event system} is very useful for inter-thread
|
||||
|
|
|
|||
Loading…
Reference in New Issue