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 <ogoffart@woboq.com>
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Sze Howe Koh 2013-09-08 16:48:04 +08:00 committed by The Qt Project
parent cddd16c2d5
commit 5852ddb110
2 changed files with 58 additions and 64 deletions

View File

@ -172,69 +172,9 @@
\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

View File

@ -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
*/
/*!