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:
parent
cddd16c2d5
commit
5852ddb110
@ -172,69 +172,9 @@
|
|||||||
|
|
||||||
\section2 Which Qt Thread Technology Should You Use?
|
\section2 Which Qt Thread Technology Should You Use?
|
||||||
|
|
||||||
Sometimes you want to do more than just running a method in the context of
|
See the \l{Multithreading Technologies in Qt} page for an introduction to the
|
||||||
another thread. You may want to have an object which lives in another
|
different approaches to multithreading to Qt, and for guidelines on how to
|
||||||
thread that provides a service to the GUI thread. Maybe you want another
|
choose among them.
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
\section1 Qt Thread Basics
|
\section1 Qt Thread Basics
|
||||||
|
@ -178,7 +178,14 @@
|
|||||||
See the \l{Qt Concurrent} module documentation for details on the individual functions.
|
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
|
\table
|
||||||
\header
|
\header
|
||||||
@ -228,6 +235,53 @@
|
|||||||
\li Yes
|
\li Yes
|
||||||
\endtable
|
\endtable
|
||||||
\sup{\e{*Except QtConcurrent::run(), which is like QRunnable}}
|
\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
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user