diff options
Diffstat (limited to 'src/corelib/doc/src')
-rw-r--r-- | src/corelib/doc/src/threads-basics.qdoc | 105 | ||||
-rw-r--r-- | src/corelib/doc/src/threads.qdoc | 213 |
2 files changed, 174 insertions, 144 deletions
diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc index dd5267f0ba..5a5c003210 100644 --- a/src/corelib/doc/src/threads-basics.qdoc +++ b/src/corelib/doc/src/threads-basics.qdoc @@ -172,109 +172,16 @@ \section2 Which Qt Thread Technology Should You Use? - Sometimes you want to do more than just running a method in the context of - another thread. You may want to have an object which lives in another - thread that provides a service to the GUI thread. Maybe you want another - thread to stay alive forever to poll hardware ports and send a signal to - the GUI thread when something noteworthy has happened. Qt provides - different solutions for developing threaded applications. The right - solution depends on the purpose of the new thread as well as on the - thread's lifetime. - - \table - \header - \li Lifetime of thread - \li Development task - \li Solution - \row - \li One call - \li Run one method within another thread and quit the thread when the - method is finished. - \li Qt provides different solutions: - \list - \li Write a function and run it with QtConcurrent::run() - \li Derive a class from QRunnable and run it in the global thread - pool with QThreadPool::globalInstance()->start() - \li Derive a class from QThread, reimplement the QThread::run() - method and use QThread::start() to run it. - \endlist - - \row - \li One call - \li Operations are to be performed on all items of a container. - Processing should be performed using all available cores. A common - example is to produce thumbnails from a list of images. - \li QtConcurrent provides the \l{QtConcurrent::}{map()} function for - applying operations on every container element, - \l{QtConcurrent::}{filter()} for selecting container elements, and - the option of specifying a reduce function for combining the - remaining elements. - \row - \li One call - \li A long running operation has to be put in another thread. During the - course of processing, status information should be sent to the GUI - thread. - \li Use QThread, reimplement run and emit signals as needed. Connect the - signals to the GUI thread's slots using queued signal/slot - connections. - - \row - \li Permanent - \li Have an object living in another thread and let it perform different - tasks upon request. - This means communication to and from the worker thread is required. - \li Derive a class from QObject and implement the necessary slots and - signals, move the object to a thread with a running event loop and - communicate with the object over queued signal/slot connections. - \row - \li Permanent - \li Have an object living in another thread, let the object perform - repeated tasks such as polling a port and enable communication with - the GUI thread. - \li Same as above but also use a timer in the worker thread to implement - polling. However, the best solution for polling is to avoid it - completely. Sometimes using QSocketNotifier is an alternative. - \endtable + See the \l{Multithreading Technologies in Qt} page for an introduction to the + different approaches to multithreading to Qt, and for guidelines on how to + choose among them. \section1 Qt Thread Basics - QThread is a very convenient cross platform abstraction of native platform - threads. Starting a thread is very simple. Let us look at a short piece of - code that generates another thread which says hello in that thread and then - exits. - - \snippet ../widgets/tutorials/threads/hellothread/hellothread.h 1 - - We derive a class from QThread and reimplement the \l{QThread::}{run()} - method. - - \snippet ../widgets/tutorials/threads/hellothread/hellothread.cpp 1 - - The run method contains the code that will be run in a separate thread. In - this example, a message containing the thread ID will be printed. - QThread::start() will call the method in another thread. - - \snippet ../widgets/tutorials/threads/hellothread/main.cpp 1 - - To start the thread, our thread object needs to be instantiated. The - \l{QThread::}{start()} method creates a new thread and calls the - reimplemented \l{QThread::}{run()} method in this new thread. Right after - \l{QThread::}{start()} is called, two program counters walk through the - program code. The main function starts with only the GUI thread running and - it should terminate with only the GUI thread running. Exiting the program - when another thread is still busy is a programming error, and therefore, - wait is called which blocks the calling thread until the - \l{QThread::}{run()} method has completed. - - This is the result of running the code: - - \code - //bad code - hello from GUI thread 3079423696 - hello from worker thread 3076111216 - \endcode - + The following sections describe how QObjects interact with threads, how + programs can safely access data from multiple threads, and how asynchronous + execution produces results without blocking a thread. \section2 QObject and Threads diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 67a986d73e..9b80f0d200 100644 --- a/src/corelib/doc/src/threads.qdoc +++ b/src/corelib/doc/src/threads.qdoc @@ -41,7 +41,7 @@ \ingroup frameworks-technologies - \nextpage Starting Threads with QThread + \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 @@ -59,7 +59,7 @@ \list \li \l{Recommended Reading} \li \l{The Threading Classes} - \li \l{Starting Threads with QThread} + \li \l{Multithreading Technologies in Qt} \li \l{Synchronizing Threads} \li \l{Reentrancy and Thread-Safety} \li \l{Threads and QObjects} @@ -112,59 +112,182 @@ */ /*! - \page threads-starting.html - \title Starting Threads with QThread + \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 - A QThread instance represents a thread and provides the means to - \l{QThread::start()}{start()} a thread, which will then execute the - reimplementation of QThread::run(). The \c run() implementation is for a - thread what the \c main() entry point is for the application. All code - executed in a call stack that starts in the \c run() function is executed - by the new thread, and the thread finishes when the function returns. - QThread emits signals to indicate that the thread started or finished - executing. - - \section1 Creating a Thread - - To create a thread, subclass QThread and reimplement its - \l{QThread::run()}{run()} function. For example: - - \snippet threads/threads.h 0 - \codeline - \snippet threads/threads.cpp 0 - \snippet threads/threads.cpp 1 - \dots - \snippet threads/threads.cpp 2 - - \section1 Starting a Thread - - Then, create an instance of the thread object and call - QThread::start(). Note that you must create the QApplication (or - QCoreApplication) object before you can create a QThread. - - The function will return immediately and the - main thread will continue. The code that appears in the - \l{QThread::run()}{run()} reimplementation will then be executed - in a separate thread. - - Creating threads is explained in more detail in the QThread - documentation. - - Note that QCoreApplication::exec() must always be called from the - main thread (the thread that executes \c{main()}), not from a - QThread. In GUI applications, the main thread is also called the - GUI thread because it's the only thread that is allowed to - perform GUI-related operations. + Qt offers many classes and functions for working with threads. Below are + three 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 QThread + and QRunnable, these functions do not require the use of low-level threading + primitives such as mutexes or semaphores. \l {Qt Concurrent} will automatically + adjust the number of threads used according to the number of processor cores + available, so applications written today will continue to scale when deployed + later on a system with more cores. + + This module also provides the QtConcurrent::run() function, which can run + any function in a thread managed by the global QThreadPool. + + See the \l{Qt Concurrent} module documentation for details on the individual functions. + + + \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/Characteristic + \li QThread + \li QRunnable + \li Qt Concurrent\sup{*} + \row + \li Supports different thread priorities + \li Yes + \li + \li + \row + \li Supports an event loop + \li Yes + \li + \li + \row + \li Supports transferring data to the thread using signals + \li Yes (received by a worker QObject) + \li + \li + \row + \li Supports controlling the thread using signals + \li Yes (received by QThread) + \li + \li Yes (received by QFutureWatcher) + \row + \li Supports thread reuse + \li + \li Yes + \li Yes + \row + \li Task-oriented + \li + \li Yes + \li Yes + \row + \li High level API + \li + \li + \li Yes + \row + \li Supports pausing/resuming/canceling + \li + \li + \li Yes + \endtable + \sup{\e{*Except QtConcurrent::run(), which is like QRunnable}} + + + \section2 Example Use Cases + + \table + \header + \li Lifetime of thread + \li Operation + \li Solution + \row + \li One call + \li Run a 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 QtConcurrent::run(). Write to a \l{Synchronizing + Threads}{thread-safe variable} to update progress. + \endlist + \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::}{filterReduced()} and \l{QtConcurrent::}{mapReduced()} + instead. + \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 Starting Threads with QThread + \previouspage Multithreading Technologies in Qt \contentspage Thread Support in Qt \nextpage Reentrancy and Thread-Safety |