From cddd16c2d564148f4d97dac894a054de1728641a Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Tue, 10 Sep 2013 19:23:38 +0800 Subject: Doc: Add an overview page to compare multithreading techniques Change-Id: I75e67ecb96423a3ebd82b32e6855378a73463fb7 Reviewed-by: Jerome Pasion Reviewed-by: Thiago Macieira --- src/corelib/doc/src/threads.qdoc | 122 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) (limited to 'src/corelib/doc/src/threads.qdoc') diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 160b717715..3d11c736cf 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,6 +59,7 @@ \list \li \l{Recommended Reading} \li \l{The Threading Classes} + \li \l{Multithreading Technologies in Qt} \li \l{Starting Threads with QThread} \li \l{Synchronizing Threads} \li \l{Reentrancy and Thread-Safety} @@ -111,11 +112,130 @@ 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 Starting Threads with QThread + + 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 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}} +*/ + /*! \page threads-starting.html \title Starting Threads with QThread \contentspage Thread Support in Qt + \previouspage Multithreading Technologies in Qt \nextpage Synchronizing Threads A QThread instance represents a thread and provides the means to -- cgit v1.2.3 From 5852ddb110e63cc9d2271431a7776978c2249877 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Sun, 8 Sep 2013 16:48:04 +0800 Subject: Doc: Move multithreading guidelines to the overview page It's helpful to see how to choose among different solutions, right after seeing short descriptions of all the solutions. - Some minor rewording was done during the move - The example about polling ports in a new thread was removed because there are better ways to do that without threads. Change-Id: I2cb571a4dbf9be93fb0ec88c60fb7406996c345b Reviewed-by: Olivier Goffart Reviewed-by: Jerome Pasion Reviewed-by: Thiago Macieira --- src/corelib/doc/src/threads.qdoc | 56 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'src/corelib/doc/src/threads.qdoc') diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 3d11c736cf..79bd7a62a3 100644 --- a/src/corelib/doc/src/threads.qdoc +++ b/src/corelib/doc/src/threads.qdoc @@ -178,7 +178,14 @@ See the \l{Qt Concurrent} module documentation for details on the individual functions. - \section1 Comparison of Solutions + \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 @@ -228,6 +235,53 @@ \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 */ /*! -- cgit v1.2.3 From 6780f76ee0e9122b8c15861a85fd29a908724d72 Mon Sep 17 00:00:00 2001 From: Sze Howe Koh Date: Sun, 8 Sep 2013 17:33:41 +0800 Subject: Doc: Remove page about how to start QThreads Multiple issues: - Incomplete: It doesn't talk about instantiating a raw QThread - Redundant: Its contents are already presented in QThread's class ref - Incorrect: It is legal to create a QThread before a QCoreApplication - Irrelevant: The bit about QCoreApplication::exec() and the etymology of "GUI thread" is unrelated to the topic of starting threads Also remove snippets that are no longer used Change-Id: Ice1819845b5b2cf843719edaa7b0f4bbb1e8bd97 Reviewed-by: Olivier Goffart Reviewed-by: Jerome Pasion Reviewed-by: Thiago Macieira --- src/corelib/doc/src/threads.qdoc | 55 ++-------------------------------------- 1 file changed, 2 insertions(+), 53 deletions(-) (limited to 'src/corelib/doc/src/threads.qdoc') diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc index 79bd7a62a3..27aca86406 100644 --- a/src/corelib/doc/src/threads.qdoc +++ b/src/corelib/doc/src/threads.qdoc @@ -60,7 +60,6 @@ \li \l{Recommended Reading} \li \l{The Threading Classes} \li \l{Multithreading Technologies in Qt} - \li \l{Starting Threads with QThread} \li \l{Synchronizing Threads} \li \l{Reentrancy and Thread-Safety} \li \l{Threads and QObjects} @@ -122,7 +121,7 @@ \contentspage Thread Support in Qt \previouspage Thread Support in Qt - \nextpage Starting Threads with QThread + \nextpage Synchronizing Threads Qt offers many classes and functions for working with threads. Below are three different approaches that Qt programmers can use to implement @@ -284,61 +283,11 @@ \endtable */ -/*! - \page threads-starting.html - \title Starting Threads with QThread - - \contentspage Thread Support in Qt - \previouspage Multithreading Technologies 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. -*/ - /*! \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 -- cgit v1.2.3