| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \group thread |
| \brief How to develop multithreaded applications. |
| \title Threading Classes |
| |
| These \l{Qt Core} classes provide threading support to applications. |
| The \l{Thread Support in Qt} page covers how to use these classes. |
| */ |
| |
| /*! |
| \page threads.html |
| \title Thread Support in Qt |
| \ingroup qt-basic-concepts |
| \brief A detailed discussion of thread handling in Qt. |
| |
| \ingroup frameworks-technologies |
| |
| \nextpage Multithreading Technologies in Qt |
| |
| Qt provides thread support in the form of platform-independent |
| threading classes, a thread-safe way of posting events, and |
| signal-slot connections across threads. This makes it easy to |
| develop portable multithreaded Qt applications and take advantage |
| of multiprocessor machines. Multithreaded programming is also a |
| useful paradigm for performing time-consuming operations without |
| freezing the user interface of an application. |
| |
| Earlier versions of Qt offered an option to build the library |
| without thread support. Since Qt 4.0, threads are always enabled. |
| |
| \section1 Topics: |
| |
| These articles assume that the reader has basic knowledge about |
| multithreaded applications. |
| |
| \list |
| \li \l{The Threading Classes} |
| \li \l{Multithreading Technologies in Qt} |
| \li \l{Synchronizing Threads} |
| \li \l{Reentrancy and Thread-Safety} |
| \li \l{Threads and QObjects} |
| \li \l{Thread-Support in Qt Modules} |
| \endlist |
| |
| |
| \section1 The Threading Classes |
| |
| These classes are relevant to threaded applications. |
| |
| \annotatedlist thread |
| |
| \omit |
| \list |
| \li QThread provides the means to start a new thread. |
| \li QThreadStorage provides per-thread data storage. |
| \li QThreadPool manages a pool of threads that run QRunnable objects. |
| \li QRunnable is an abstract class representing a runnable object. |
| \li QMutex provides a mutual exclusion lock, or mutex. |
| \li QMutexLocker is a convenience class that automatically locks |
| and unlocks a QMutex. |
| \li QReadWriteLock provides a lock that allows simultaneous read access. |
| \li QReadLocker and QWriteLocker are convenience classes that automatically |
| lock and unlock a QReadWriteLock. |
| \li QSemaphore provides an integer semaphore (a generalization of a mutex). |
| \li QWaitCondition provides a way for threads to go to sleep until |
| woken up by another thread. |
| \li QAtomicInt provides atomic operations on integers. |
| \li QAtomicPointer provides atomic operations on pointers. |
| \endlist |
| \endomit |
| |
| \note Qt's threading classes are implemented with native threading APIs; |
| e.g., Win32 and pthreads. Therefore, they can be used with threads of the |
| same native API. |
| */ |
| |
| /*! |
| \page threads-technologies.html |
| \title Multithreading Technologies in Qt |
| \ingroup qt-basic-concepts |
| \brief An overview and comparison of different ways to use threads in Qt. |
| |
| \ingroup frameworks-technologies |
| |
| \contentspage Thread Support in Qt |
| \previouspage Thread Support in Qt |
| \nextpage Synchronizing Threads |
| |
| Qt offers many classes and functions for working with threads. Below are |
| four different approaches that Qt programmers can use to implement |
| multithreaded applications. |
| |
| |
| \section1 QThread: Low-Level API with Optional Event Loops |
| |
| QThread is the foundation of all thread control in Qt. Each QThread |
| instance represents and controls one thread. |
| |
| QThread can either be instantiated directly or subclassed. Instantiating a |
| QThread provides a parallel event loop, allowing QObject slots to be invoked |
| in a secondary thread. Subclassing a QThread allows the application to initialize |
| the new thread before starting its event loop, or to run parallel code |
| without an event loop. |
| |
| See the \l{QThread}{QThread class reference} and the \l{Threading and |
| Concurrent Programming Examples}{threading examples} for demonstrations on |
| how to use QThread. |
| |
| |
| \section1 QThreadPool and QRunnable: Reusing Threads |
| |
| Creating and destroying threads frequently can be expensive. To reduce this |
| overhead, existing threads can be reused for new tasks. QThreadPool is a |
| collection of reuseable QThreads. |
| |
| To run code in one of a QThreadPool's threads, reimplement QRunnable::run() |
| and instantiate the subclassed QRunnable. Use QThreadPool::start() to put |
| the QRunnable in the QThreadPool's run queue. When a thread becomes available, |
| the code within QRunnable::run() will execute in that thread. |
| |
| Each Qt application has a global thread pool, which is accessible through |
| QThreadPool::globalInstance(). This global thread pool automatically maintains |
| an optimal number of threads based on the number of cores in the CPU. However, |
| a separate QThreadPool can be created and managed explicitly. |
| |
| |
| \section1 Qt Concurrent: Using a High-level API |
| |
| The \l{Qt Concurrent} module provides high-level functions that deal with some |
| common parallel computation patterns: map, filter, and reduce. Unlike using |
| QThread and QRunnable, these functions never require the use of \l{Synchronizing |
| Threads#Low-Level Synchronization Primitives}{low-level threading primitives} |
| such as mutexes or semaphores. Instead, they return a QFuture object which can |
| be used to retrieve the functions' results when they are ready. QFuture can |
| also be used to query computation progress and to pause/resume/cancel the |
| computation. For convenience, QFutureWatcher enables interactions with |
| \l{QFuture}s via signals and slots. |
| |
| \l{Qt Concurrent}'s map, filter and reduce algorithms automatically distribute |
| computation across all available processor cores, so applications written today |
| will continue to scale when deployed later on a system with more cores. |
| |
| This module also provides the \l {QtConcurrent::run}() function, which can run any |
| function in another thread. However, \l {QtConcurrent::run}() only supports a subset |
| of features available to the map, filter and reduce functions. The QFuture |
| can be used to retrieve the function's return value and to check if the thread |
| is running. However, a call to \l{QtConcurrent::run}() uses one thread only, cannot |
| be paused/resumed/canceled, and cannot be queried for progress. |
| |
| See the \l{Qt Concurrent} module documentation for details on the individual functions. |
| |
| |
| \section1 WorkerScript: Threading in QML |
| |
| The WorkerScript QML type lets JavaScript code run in parallel with the GUI |
| thread. |
| |
| Each WorkerScript instance can have one \c{.js} script attached to it. When |
| \l {QtQml.WorkerScript::WorkerScript::sendMessage()}{WorkerScript.sendMessage}() is |
| called, the script will run in a separate thread (and a separate |
| \l{QQmlContext}{QML context}). When the script finishes running, it can |
| send a reply back to the GUI thread which will invoke the |
| \l {QtQml.WorkerScript::WorkerScript::message()}{WorkerScript.onMessage}() |
| signal handler. |
| |
| Using a WorkerScript is similar to using a worker QObject that has been moved |
| to another thread. Data is transferred between threads via signals. |
| |
| See the WorkerScript documentation for details on how to implement the script, |
| and for a list of data types that can be passed between threads. |
| |
| |
| \section1 Choosing an Appropriate Approach |
| |
| As demonstrated above, Qt provides different solutions for developing threaded |
| applications. The right solution for a given application depends on the purpose |
| of the new thread and the thread's lifetime. Below is a comparison of Qt's |
| threading technologies, followed by recommended solutions for some example use cases. |
| |
| \section2 Comparison of Solutions |
| |
| \table |
| \header |
| \li Feature |
| \li QThread |
| \li QRunnable and QThreadPool |
| \li \l {QtConcurrent::run}() |
| \li Qt Concurrent (Map, Filter, Reduce) |
| \li WorkerScript |
| \row |
| \li Language |
| \li C++ |
| \li C++ |
| \li C++ |
| \li C++ |
| \li QML |
| \row |
| \li Thread priority can be specified |
| \li Yes |
| \li Yes |
| \li |
| \li |
| \li |
| \row |
| \li Thread can run an event loop |
| \li Yes |
| \li |
| \li |
| \li |
| \li |
| \row |
| \li Thread can receive data updates through signals |
| \li Yes (received by a worker QObject) |
| \li |
| \li |
| \li |
| \li Yes (received by WorkerScript) |
| \row |
| \li Thread can be controlled using signals |
| \li Yes (received by QThread) |
| \li |
| \li |
| \li Yes (received by QFutureWatcher) |
| \li |
| \row |
| \li Thread can be monitored through a QFuture |
| \li |
| \li |
| \li Partially |
| \li Yes |
| \li |
| \row |
| \li Built-in ability to pause/resume/cancel |
| \li |
| \li |
| \li |
| \li Yes |
| \li |
| \endtable |
| |
| |
| \section2 Example Use Cases |
| |
| \table |
| \header |
| \li Lifetime of thread |
| \li Operation |
| \li Solution |
| \row |
| \li One call |
| \li Run a new linear function within another thread, optionally with progress |
| updates during the run. |
| \li Qt provides different solutions: |
| \list |
| \li Place the function in a reimplementation of QThread::run() and |
| start the QThread. Emit signals to update progress. OR |
| \li Place the function in a reimplementation of QRunnable::run() and |
| add the QRunnable to a QThreadPool. Write to a \l{Synchronizing |
| Threads}{thread-safe variable} to update progress. OR |
| \li Run the function using \l {QtConcurrent::run}(). Write to a \l{Synchronizing |
| Threads}{thread-safe variable} to update progress. |
| \endlist |
| \row |
| \li One call |
| \li Run an existing function within another thread and get its return value. |
| \li Run the function using \l{QtConcurrent::run}(). Have a QFutureWatcher emit |
| the \l{QFutureWatcher::}{finished()} signal when the function has |
| returned, and call QFutureWatcher::result() to get the function's return |
| value. |
| \row |
| \li One call |
| \li Perform an operation on all items of a container, using all available |
| cores. For example, producing thumbnails from a list of images. |
| \li Use Qt Concurrent's \l{QtConcurrent::filter}() function to select |
| container elements, and the \l{QtConcurrent::map}() function to apply |
| an operation to each element. To fold the output into a single result, |
| use \l{QtConcurrent::filteredReduced}() and |
| \l{QtConcurrent::mappedReduced}() instead. |
| \row |
| \li One call/Permanent |
| \li Perfrom a long computation in a pure QML application, and update the GUI |
| when the results are ready. |
| \li Place the computation code in a \c{.js} script and attach it to a |
| WorkerScript instance. Call |
| \l{QtQml.WorkerScript::WorkerScript::sendMessage()} |
| {WorkerScript.sendMessage}() to start the computation in a new |
| thread. Let the script call sendMessage() too, to pass the result |
| back to the GUI thread. Handle the result in \c onMessage and |
| update the GUI there. |
| \row |
| \li Permanent |
| \li Have an object living in another thread that can perform different |
| tasks upon request and/or can receive new data to work with. |
| \li Subclass a QObject to create a worker. Instantiate this worker object |
| and a QThread. Move the worker to the new thread. Send commands or |
| data to the worker object over queued signal-slot connections. |
| \row |
| \li Permanent |
| \li Repeatedly perform an expensive operation in another thread, where the |
| thread does not need to receive any signals or events. |
| \li Write the infinite loop directly within a reimplementation of QThread::run(). |
| Start the thread without an event loop. Let the thread emit signals to |
| send data back to the GUI thread. |
| \endtable |
| */ |
| |
| /*! |
| \page threads-synchronizing.html |
| \title Synchronizing Threads |
| |
| \previouspage Multithreading Technologies in Qt |
| \contentspage Thread Support in Qt |
| \nextpage Reentrancy and Thread-Safety |
| |
| While the purpose of threads is to allow code to run in parallel, |
| there are times where threads must stop and wait for other |
| threads. For example, if two threads try to write to the same |
| variable simultaneously, the result is undefined. The principle of |
| forcing threads to wait for one another is called \e{mutual exclusion}. |
| It is a common technique for protecting shared resources such as data. |
| |
| Qt provides low-level primitives as well as high-level mechanisms |
| for synchronizing threads. |
| |
| \section1 Low-Level Synchronization Primitives |
| |
| QMutex is the basic class for enforcing mutual exclusion. A thread |
| locks a mutex in order to gain access to a shared resource. If a second |
| thread tries to lock the mutex while it is already locked, the second |
| thread will be put to sleep until the first thread completes its task |
| and unlocks the mutex. |
| |
| QReadWriteLock is similar to QMutex, except that it distinguishes |
| between "read" and "write" access. When a piece of data is not being |
| written to, it is safe for multiple threads to read from it simultaneously. |
| A QMutex forces multiple readers to take turns to read shared data, but a |
| QReadWriteLock allows simultaneous reading, thus improving parallelism. |
| |
| QSemaphore is a generalization of QMutex that protects a certain |
| number of identical resources. In contrast, a QMutex protects |
| exactly one resource. The \l{Semaphores Example} shows a typical application |
| of semaphores: synchronizing access to a circular buffer between a producer |
| and a consumer. |
| |
| QWaitCondition synchronizes threads not by enforcing mutual exclusion but by |
| providing a \e{condition variable}. While the other primitives make threads |
| wait until a resource is unlocked, QWaitCondition makes threads wait until a |
| particular condition has been met. To allow the waiting threads to proceed, |
| call \l{QWaitCondition::wakeOne()}{wakeOne()} to wake one randomly |
| selected thread or \l{QWaitCondition::wakeAll()}{wakeAll()} to wake them all |
| simultaneously. The \l{Wait Conditions Example} shows how to solve the |
| producer-consumer problem using QWaitCondition instead of QSemaphore. |
| |
| \note Qt's synchronization classes rely on the use of properly |
| 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 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 QReadWriteLock, 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 |
| communication. Every thread may have its own event loop. To call a slot (or |
| any \l{Q_INVOKABLE}{invokable} method) in another thread, place that call in |
| the target thread's event loop. This lets the target thread finish its current |
| task before the slot starts running, while the original thread continues |
| running in parallel. |
| |
| To place an invocation in an event loop, make a queued \l{Signals & Slots} |
| {signal-slot} connection. Whenever the signal is emitted, its arguments will |
| be recorded by the event system. The thread that the signal receiver |
| \l{QObject#Thread Affinity}{lives in} will then run the slot. Alternatively, |
| call QMetaObject::invokeMethod() to achieve the same effect without signals. |
| In both cases, a \l{Qt::QueuedConnection}{queued connection} must be used |
| because a \l{Qt::DirectConnection}{direct connection} bypasses the event |
| system and runs the method immediately in the current thread. |
| |
| There is no risk of deadlocks when using the event system for thread |
| synchronization, unlike using low-level primitives. However, the event system |
| does not enforce mutual exclusion. If invokable methods access shared data, |
| they must still be protected with low-level primitives. |
| |
| Having said that, Qt's event system, along with \l{Implicit Sharing}{implicitly |
| shared} data structures, offers an alternative to traditional thread locking. |
| If signals and slots are used exclusively and no variables are shared between |
| threads, a multithreaded program can do without low-level primitives altogether. |
| |
| \sa QThread::exec(), {Threads and QObjects} |
| */ |
| |
| /*! |
| \page threads-reentrancy.html |
| \title Reentrancy and Thread-Safety |
| |
| \keyword reentrant |
| \keyword thread-safe |
| |
| \previouspage Synchronizing Threads |
| \contentspage Thread Support in Qt |
| \nextpage Threads and QObjects |
| |
| Throughout the documentation, the terms \e{reentrant} and |
| \e{thread-safe} are used to mark classes and functions to indicate |
| how they can be used in multithread applications: |
| |
| \list |
| \li A \e thread-safe function can be called simultaneously from |
| multiple threads, even when the invocations use shared data, |
| because all references to the shared data are serialized. |
| \li A \e reentrant function can also be called simultaneously from |
| multiple threads, but only if each invocation uses its own data. |
| \endlist |
| |
| Hence, a \e{thread-safe} function is always \e{reentrant}, but a |
| \e{reentrant} function is not always \e{thread-safe}. |
| |
| By extension, a class is said to be \e{reentrant} if its member |
| functions can be called safely from multiple threads, as long as |
| each thread uses a \e{different} instance of the class. The class |
| is \e{thread-safe} if its member functions can be called safely |
| from multiple threads, even if all the threads use the \e{same} |
| instance of the class. |
| |
| \note Qt classes are only documented as \e{thread-safe} if they |
| are intended to be used by multiple threads. If a function is not |
| marked as thread-safe or reentrant, it should not be used from |
| different threads. If a class is not marked as thread-safe or |
| reentrant then a specific instance of that class should not be |
| accessed from different threads. |
| |
| \section1 Reentrancy |
| |
| C++ classes are often reentrant, simply because they only access |
| their own member data. Any thread can call a member function on an |
| instance of a reentrant class, as long as no other thread can call |
| a member function on the \e{same} instance of the class at the |
| same time. For example, the \c Counter class below is reentrant: |
| |
| \snippet snippets/threads/threads.cpp 3 |
| \snippet snippets/threads/threads.cpp 4 |
| |
| The class isn't thread-safe, because if multiple threads try to |
| modify the data member \c n, the result is undefined. This is |
| because the \c ++ and \c -- operators aren't always atomic. |
| Indeed, they usually expand to three machine instructions: |
| |
| \list 1 |
| \li Load the variable's value in a register. |
| \li Increment or decrement the register's value. |
| \li Store the register's value back into main memory. |
| \endlist |
| |
| If thread A and thread B load the variable's old value |
| simultaneously, increment their register, and store it back, they |
| end up overwriting each other, and the variable is incremented |
| only once! |
| |
| \section1 Thread-Safety |
| |
| Clearly, the access must be serialized: Thread A must perform |
| steps 1, 2, 3 without interruption (atomically) before thread B |
| can perform the same steps; or vice versa. An easy way to make |
| the class thread-safe is to protect all access to the data |
| members with a QMutex: |
| |
| \snippet snippets/threads/threads.cpp 5 |
| \snippet snippets/threads/threads.cpp 6 |
| |
| The QMutexLocker class automatically locks the mutex in its |
| constructor and unlocks it when the destructor is invoked, at the |
| end of the function. Locking the mutex ensures that access from |
| different threads will be serialized. The \c mutex data member is |
| declared with the \c mutable qualifier because we need to lock |
| and unlock the mutex in \c value(), which is a const function. |
| |
| \section1 Notes on Qt Classes |
| |
| Many Qt classes are \e{reentrant}, but they are not made |
| \e{thread-safe}, because making them thread-safe would incur the |
| extra overhead of repeatedly locking and unlocking a QMutex. For |
| example, QString is reentrant but not thread-safe. You can safely |
| access \e{different} instances of QString from multiple threads |
| simultaneously, but you can't safely access the \e{same} instance |
| of QString from multiple threads simultaneously (unless you |
| protect the accesses yourself with a QMutex). |
| |
| Some Qt classes and functions are thread-safe. These are mainly |
| the thread-related classes (e.g. QMutex) and fundamental functions |
| (e.g. QCoreApplication::postEvent()). |
| |
| \note Terminology in the multithreading domain isn't entirely |
| standardized. POSIX uses definitions of reentrant and thread-safe |
| that are somewhat different for its C APIs. When using other |
| object-oriented C++ class libraries with Qt, be sure the |
| definitions are understood. |
| */ |
| |
| /*! |
| \page threads-qobject.html |
| \title Threads and QObjects |
| |
| \previouspage Reentrancy and Thread Safety |
| \contentspage Thread Support in Qt |
| \nextpage Thread-Support in Qt Modules |
| |
| QThread inherits QObject. It emits signals to indicate that the |
| thread started or finished executing, and provides a few slots as |
| well. |
| |
| More interesting is that \l{QObject}s can be used in multiple |
| threads, emit signals that invoke slots in other threads, and |
| post events to objects that "live" in other threads. This is |
| possible because each thread is allowed to have its own event |
| loop. |
| |
| \section1 QObject Reentrancy |
| |
| QObject is reentrant. Most of its non-GUI subclasses, such as |
| QTimer, QTcpSocket, QUdpSocket and QProcess, are also |
| reentrant, making it possible to use these classes from multiple |
| threads simultaneously. Note that these classes are designed to be |
| created and used from within a single thread; creating an object |
| in one thread and calling its functions from another thread is not |
| guaranteed to work. There are three constraints to be aware of: |
| |
| \list |
| \li \e{The child of a QObject must always be created in the thread |
| where the parent was created.} This implies, among other |
| things, that you should never pass the QThread object (\c |
| this) as the parent of an object created in the thread (since |
| the QThread object itself was created in another thread). |
| |
| \li \e{Event driven objects may only be used in a single thread.} |
| Specifically, this applies to the \l{timers.html}{timer |
| mechanism} and the \l{QtNetwork}{network module}. For example, |
| you cannot start a timer or connect a socket in a thread that |
| is not the \l{QObject::thread()}{object's thread}. |
| |
| \li \e{You must ensure that all objects created in a thread are |
| deleted before you delete the QThread.} This can be done |
| easily by creating the objects on the stack in your |
| \l{QThread::run()}{run()} implementation. |
| \endlist |
| |
| Although QObject is reentrant, the GUI classes, notably QWidget |
| and all its subclasses, are not reentrant. They can only be used |
| from the main thread. As noted earlier, QCoreApplication::exec() |
| must also be called from that thread. |
| |
| In practice, the impossibility of using GUI classes in other |
| threads than the main thread can easily be worked around by |
| putting time-consuming operations in a separate worker thread and |
| displaying the results on screen in the main thread when the |
| worker thread is finished. This is the approach used for |
| implementing the \l{Mandelbrot Example} and |
| the \l{Blocking Fortune Client Example}. |
| |
| In general, creating QObjects before the QApplication is not supported |
| and can lead to weird crashes on exit, depending on the platform. |
| This means static instances of QObject are also not supported. A |
| properly structured single or multi-threaded application should make |
| the QApplication be the first created, and last destroyed QObject. |
| |
| \section1 Per-Thread Event Loop |
| |
| Each thread can have its own event loop. The initial thread starts |
| its event loop using QCoreApplication::exec(), or for |
| single-dialog GUI applications, sometimes QDialog::exec(). |
| Other threads can start an event loop using QThread::exec(). |
| Like QCoreApplication, QThread provides an \l{QThread::exit()}{exit(int)} |
| function and a \l{QThread::quit()}{quit()} slot. |
| |
| An event loop in a thread makes it possible for the thread to use |
| certain non-GUI Qt classes that require the presence of an event |
| loop (such as QTimer, QTcpSocket, and QProcess). It also makes it |
| possible to connect signals from any threads to slots of a |
| specific thread. This is explained in more detail in the |
| \l{Signals and Slots Across Threads} section below. |
| |
| \image threadsandobjects.png Threads, objects, and event loops |
| |
| A QObject instance is said to \e live in the thread in which it |
| is created. Events to that object are dispatched by that thread's |
| event loop. The thread in which a QObject lives is available using |
| QObject::thread(). |
| |
| The QObject::moveToThread() function changes the thread affinity for |
| an object and its children (the object cannot be moved if it has a |
| parent). |
| |
| Calling \c delete on a QObject from a thread other than the one |
| that \e owns the object (or accessing the object in other ways) is |
| unsafe, unless you guarantee that the object isn't processing |
| events at that moment. Use QObject::deleteLater() instead, and a |
| \l{QEvent::DeferredDelete}{DeferredDelete} event will be posted, |
| which the event loop of the object's thread will eventually pick |
| up. By default, the thread that \e owns a QObject is the thread |
| that \e creates the QObject, but not after QObject::moveToThread() |
| has been called. |
| |
| If no event loop is running, events won't be delivered to the |
| object. For example, if you create a QTimer object in a thread but |
| never call \l{QThread::exec()}{exec()}, the QTimer will never emit |
| its \l{QTimer::timeout()}{timeout()} signal. Calling |
| \l{QObject::deleteLater()}{deleteLater()} won't work |
| either. (These restrictions apply to the main thread as well.) |
| |
| You can manually post events to any object in any thread at any |
| time using the thread-safe function |
| QCoreApplication::postEvent(). The events will automatically be |
| dispatched by the event loop of the thread where the object was |
| created. |
| |
| Event filters are supported in all threads, with the restriction |
| that the monitoring object must live in the same thread as the |
| monitored object. Similarly, QCoreApplication::sendEvent() |
| (unlike \l{QCoreApplication::postEvent()}{postEvent()}) can only |
| be used to dispatch events to objects living in the thread from |
| which the function is called. |
| |
| \section1 Accessing QObject Subclasses from Other Threads |
| |
| QObject and all of its subclasses are not thread-safe. This |
| includes the entire event delivery system. It is important to keep |
| in mind that the event loop may be delivering events to your |
| QObject subclass while you are accessing the object from another |
| thread. |
| |
| If you are calling a function on an QObject subclass that doesn't |
| live in the current thread and the object might receive events, |
| you must protect all access to your QObject subclass's internal |
| data with a mutex; otherwise, you may experience crashes or other |
| undesired behavior. |
| |
| Like other objects, QThread objects live in the thread where the |
| object was created -- \e not in the thread that is created when |
| QThread::run() is called. It is generally unsafe to provide slots |
| in your QThread subclass, unless you protect the member variables |
| with a mutex. |
| |
| On the other hand, you can safely emit signals from your |
| QThread::run() implementation, because signal emission is |
| thread-safe. |
| |
| \section1 Signals and Slots Across Threads |
| |
| Qt supports these signal-slot connection types: |
| |
| \list |
| |
| \li \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is |
| emitted in the thread which the receiving object has affinity then |
| the behavior is the same as the Direct Connection. Otherwise, |
| the behavior is the same as the Queued Connection." |
| |
| \li \l{Qt::DirectConnection}{Direct Connection} The slot is invoked |
| immediately, when the signal is emitted. The slot is executed |
| in the emitter's thread, which is not necessarily the |
| receiver's thread. |
| |
| \li \l{Qt::QueuedConnection}{Queued Connection} The slot is invoked |
| when control returns to the event loop of the receiver's |
| thread. The slot is executed in the receiver's thread. |
| |
| \li \l{Qt::BlockingQueuedConnection}{Blocking Queued Connection} |
| The slot is invoked as for the Queued Connection, except the |
| current thread blocks until the slot returns. \note Using this |
| type to connect objects in the same thread will cause deadlock. |
| |
| \li \l{Qt::UniqueConnection}{Unique Connection} The behavior is the |
| same as the Auto Connection, but the connection is made only if |
| it does not duplicate an existing connection. i.e., if the same |
| signal is already connected to the same slot for the same pair |
| of objects, then the connection is not made and connect() |
| returns \c false. |
| |
| \endlist |
| |
| The connection type can be specified by passing an additional |
| argument to \l{QObject::connect()}{connect()}. Be aware that |
| using direct connections when the sender and receiver live in |
| different threads is unsafe if an event loop is running in the |
| receiver's thread, for the same reason that calling any function |
| on an object living in another thread is unsafe. |
| |
| QObject::connect() itself is thread-safe. |
| |
| The \l{Mandelbrot Example} uses a queued |
| connection to communicate between a worker thread and the main |
| thread. To avoid freezing the main thread's event loop (and, as a |
| consequence, the application's user interface), all the |
| Mandelbrot fractal computation is done in a separate worker |
| thread. The thread emits a signal when it is done rendering the |
| fractal. |
| |
| Similarly, the \l{Blocking Fortune Client Example} uses a separate |
| thread for communicating with a TCP server asynchronously. |
| */ |
| |
| /*! |
| \page threads-modules.html |
| \title Thread-Support in Qt Modules |
| |
| \previouspage Threads and QObjects |
| \contentspage Thread Support in Qt |
| |
| \section1 Threads and the SQL Module |
| |
| A connection can only be used from within the thread that created it. |
| Moving connections between threads or creating queries from a different |
| thread is not supported. |
| |
| In addition, the third party libraries used by the QSqlDrivers can impose |
| further restrictions on using the SQL Module in a multithreaded program. |
| Consult the manual of your database client for more information |
| |
| \section1 Painting in Threads |
| |
| QPainter can be used in a thread to paint onto QImage, QPrinter, and |
| QPicture paint devices. Painting onto QPixmaps and QWidgets is \e not |
| supported. On \macos the automatic progress dialog will not be |
| displayed if you are printing from outside the GUI thread. |
| |
| Any number of threads can paint at any given time, however only |
| one thread at a time can paint on a given paint device. In other |
| words, two threads can paint at the same time if each paints onto |
| separate QImages, but the two threads cannot paint onto the same |
| QImage at the same time. |
| |
| \section1 Threads and Rich Text Processing |
| |
| The QTextDocument, QTextCursor, and \l{richtext.html}{all related classes} are reentrant. |
| |
| Note that a QTextDocument instance created in the GUI thread may |
| contain QPixmap image resources. Use QTextDocument::clone() to |
| create a copy of the document, and pass the copy to another thread for |
| further processing (such as printing). |
| |
| \section1 Threads and the SVG Module |
| |
| The QSvgGenerator and QSvgRenderer classes in the QtSvg module |
| are reentrant. |
| |
| \section1 Threads and Implicitly Shared Classes |
| |
| Qt uses an optimization called \l{implicit sharing} for many of |
| its value class, notably QImage and QString. Beginning with Qt 4, |
| implicit shared classes can safely be copied across threads, like |
| any other value classes. They are fully |
| \l{Reentrancy and Thread-Safety}{reentrant}. The implicit sharing |
| is really \e implicit. |
| |
| In many people's minds, implicit sharing and multithreading are |
| incompatible concepts, because of the way the reference counting |
| is typically done. Qt, however, uses atomic reference counting to |
| ensure the integrity of the shared data, avoiding potential |
| corruption of the reference counter. |
| |
| Note that atomic reference counting does not guarantee |
| \l{Reentrancy and Thread-Safety}{thread-safety}. Proper locking should be used |
| when sharing an instance of an implicitly shared class between |
| threads. This is the same requirement placed on all |
| \l{Reentrancy and Thread-Safety}{reentrant} classes, shared or not. Atomic reference |
| counting does, however, guarantee that a thread working on its |
| own, local instance of an implicitly shared class is safe. We |
| recommend using \l{Signals and Slots Across Threads}{signals and |
| slots} to pass data between threads, as this can be done without |
| the need for any explicit locking. |
| |
| To sum it up, implicitly shared classes in Qt 4 are really \e |
| implicitly shared. Even in multithreaded applications, you can |
| safely use them as if they were plain, non-shared, reentrant |
| value-based classes. |
| */ |