Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++
++ /*!
++ \group thread
++ \brief How to develop multithreaded applications.
++ \title Threading Classes
++
++ These \l{Qt Core} classes provide threading support to applications.
++ The \l{Multi-threading in Qt} page covers how to use these classes.
++ */
++
++ /*!
++ \page threads.html
++ \target threadsupportinqt
++ \title Multi-threading 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
++
++ \previouspage Multi-threading 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 reusable 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 Perform 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
++ \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{Producer and Consumer using 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{Producer and Consumer using 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
++ \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
++ \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 [QtNetwork] {Blocking Fortune Client}
++ {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 [QtNetwork] {Blocking Fortune Client}
++ {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
++
++ \section1 Threads and the SQL Module
++
++ A database connection must only be used from within the thread that
++ created it. Moving a connection into another thread can be done
++ with QSqlDatabase::moveToThread().
++
++ 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,
++ QPicture, and (for most platforms) QPixmap paint devices.
++ Painting onto 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
++ \l{Qt SVG C++ Classes}{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.
++ */