path: root/src
diff options
authorSze Howe Koh <>2013-11-02 10:13:45 +0800
committerThe Qt Project <>2013-11-05 00:29:01 +0100
commit6b8e866391cf933f077756c8ad154683885ea07f (patch)
tree2f74f360f1b0cf6f1078c2f06a9a01d9aee324f9 /src
parenta8351096dbe1b8c02bcae858fb03133a5dacffdd (diff)
Doc: Clean up threading examples
- Example 3 (Clock) is a collection of anti-patterns. - It implements a slot in a QThread subclass and then forces the new thread to use Qt::DirectConnection to invoke the slot in the "wrong" thread. - It talks about getting away with non-thread-safe usage - It uses a thread as a timer and then admits that it's an over- complicated approach. - Example 4 (Permanent Thread) is over-complicated yet incomplete. A better one exists in the QThread class ref. - Example 1 (Thread Pool) is covered by the QThreadPool class ref. - Example 2 (QtConcurrent::run()) is covered in the "Threading and Concurrent Programming Examples" page and the "QtConcurrentRun" page. - The undocumented "Hello Thread" example is covered in the QThread class ref. - These examples cannot be accessed from Qt Creator's Examples tool. - These examples are neither widget-related nor tutorials, contrary to their source paths. Task-number: QTBUG-33360 Change-Id: Ic79cb764ee925ddbcbeafee8e1d01db7fe0f6cfe Reviewed-by: Topi Reiniƶ <> Reviewed-by: Jerome Pasion <>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/doc/images/thread_clock.pngbin5964 -> 0 bytes
2 files changed, 3 insertions, 124 deletions
diff --git a/src/corelib/doc/images/thread_clock.png b/src/corelib/doc/images/thread_clock.png
deleted file mode 100644
index b8a8aa0a39..0000000000
--- a/src/corelib/doc/images/thread_clock.png
+++ /dev/null
Binary files differ
diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc
index 4f381421b4..2206899460 100644
--- a/src/corelib/doc/src/threads-basics.qdoc
+++ b/src/corelib/doc/src/threads-basics.qdoc
@@ -219,130 +219,9 @@
\section1 Examples
- This tutorial comes with examples for Qt's three basic ways of working with
- threads. Two more examples show how to communicate with a running thread
- and how a QObject can be placed in another thread, providing service to the
- main thread.
- \list
- \li Using QThread as shown \l{Qt thread basics}{above}
- \li \l{Example 1: Using the Thread Pool}{Using the global QThreadPool}
- \li \l{Example 2: Using QtConcurrent}{Using QtConcurrent}
- \li \l{Example 3: Clock}{Communication with the GUI thread}
- \li \l{Example 4: A Permanent Thread}{A permanent QObject in another thread
- provides service to the main thread}
- \endlist
- The following examples can all be compiled and run independently. The source can
- be found in the examples directory: examples/tutorials/threads/
- \section2 Example 1: Using the Thread Pool
- Creating and destroying threads frequently can be expensive. To avoid the
- cost of thread creation, a thread pool can be used. A thread pool is a
- place where threads can be parked and fetched. We can write the same
- "hello thread" program as \l{Qt Thread Basics}{above} using the global
- thread pool. We derive a class from QRunnable. The code we want to run in
- another thread needs to be placed in the reimplemented QRunnable::run()
- method.
- \snippet ../widgets/tutorials/threads/hellothreadpool/hellothreadpool.cpp 1
- We instantiate Work in main(), locate the global thread pool and use the
- QThreadPool::start() method. Now the thread pool runs our worker in another
- thread. Using the thread pool has a performance advantage because threads
- are not destroyed after they have finished running. They are kept in a pool
- and wait to be used again later.
- \section2 Example 2: Using QtConcurrent
- \snippet ../widgets/tutorials/threads/helloconcurrent/helloconcurrent.cpp 1
- We write a global function hello() to implement the work. QtConcurrent::run()
- is used to run the function in another thread. The result is a QFuture.
- QFuture provides a method called \l{QFuture::}{waitForFinished()}, which
- blocks until the calculation is completed. The real power of QtConcurrent
- becomes visible when data can be made available in a container. QtConcurrent
- provides several functions that are able to process itemized data on all
- available cores simultaneously. The use of QtConcurrent is very similar to
- applying an STL algorithm to an STL container.
- \l{examples-threadandconcurrent.html}{QtConcurrent Map} is a very short and
- clear example about how a container of images can be scaled on all available
- cores. The image scaling example uses the blocking variants of the functions
- used. For every blocking function there is also a non-blocking, asynchronous
- counterpart. Getting results asynchronously is implemented with QFuture and
- QFutureWatcher.
- \section2 Example 3: Clock
- \image thread_clock.png "clock"
- We want to produce a clock application. The application has a GUI and a
- worker thread. The worker thread checks every 10 milliseconds what time it
- is. If the formatted time has changed, the result will be sent to the GUI
- thread where it is displayed.
- Of course, this is an overly complicated way of designing a clock and,
- actually, a separate thread is unnecessary. We would be better off placing
- the timer in the main thread because the calculation made in the timer slot
- is very short-lived. This example is purely for instructional use and shows
- how to communicate from a worker thread to a GUI thread. Note that
- communication in this direction is easy. We only need to add a signal
- to QThread and make a queued signal/slot connection to the main thread.
- Communication from the GUI to the worker thread is shown in the next
- example.
- \snippet ../widgets/tutorials/threads/clock/main.cpp 1
- We've connected the \c clockThread with the label. The connection must be a
- queued signal-slot connection because we want to put the call in the event
- loop.
- \snippet ../widgets/tutorials/threads/clock/clockthread.h 1
- We have derived a class from QThread and declared the \c sendTime() signal.
- \snippet ../widgets/tutorials/threads/clock/clockthread.cpp 1
- The trickiest part of this example is that the timer is connected to its
- slot via a direct connection. A default connection would produce a queued
- signal-slot connection because the connected objects live in different
- threads; remember that QThread does not live in the thread it creates.
- Still it is safe to access ClockThread::timerHit() from the worker thread
- because ClockThread::timerHit() is private and only touches local variables
- and a private member that isn't touched by public methods.
- QDateTime::currentDateTime() isn't marked as thread-safe in Qt
- documentation, however we can get away with using it in this small
- example because we know that the QDateTime::currentDateTime() static
- method isn't used in any other threads.
- \section2 Example 4: A Permanent Thread
- This example shows how it is possible to have a QObject in a worker thread
- that accepts requests from the GUI thread, does polling using a timer and
- continuously reports results back to the GUI thread. The actual work
- including the polling must be implemented in a class derived from QObject.
- We have called this class \c WorkerObject in the code shown below. The
- thread-specific code is hidden in a class called \c Thread, derived from
- QThread.
- \c Thread has two additional public members. The \c launchWorker() member
- takes the worker object and moves it to another thread with a started event
- loop.
- The call blocks for a very short moment until the thread creation operation
- is completed, allowing the worker object to be used again on the next line.
- The \c Thread class's code is short but somewhat involved, so we only show
- how to use the class.
- \snippet ../widgets/tutorials/threads/movedobject/main.cpp 1
- QMetaObject::invokeMethod() calls a slot via the event loop. The worker
- object's methods should not be called directly after the object has been
- moved to another thread. We let the worker thread do some work and polling,
- and use a timer to shut the application down after 3 seconds. Shutting the
- worker down needs some care. We call \c{Thread::stop()} to exit the event
- loop. We wait for the thread to terminate and, after this has occurred, we
- delete the worker.
+ Qt comes with several examples for using threads. See the class references
+ for QThread and QThreadPool for simple examples. See the \l{Threading and
+ Concurrent Programming Examples} page for more advanced ones.
\section1 Digging Deeper