summaryrefslogtreecommitdiffstats
path: root/src/corelib/doc/src/threads-basics.qdoc
blob: 2206899460ce67dd8fc5f2b6fcc16ed56c1d50d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.  Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \page thread-basics.html
    \ingroup tutorials
    \startpage {index.html}{Qt Reference Documentation}

    \title Threading Basics
    \brief An introduction to threads

    \section1 What Are Threads?

    Threads are about doing things in parallel, just like processes. So how do
    threads differ from processes? While you are making calculations on a
    spreadsheet, there may also be a media player running on the same desktop
    playing your favorite song. Here is an example of two processes working in
    parallel: one running the spreadsheet program; one running a media player.
    Multitasking is a well known term for this. A closer look at the media
    player reveals that there are again things going on in parallel within one
    single process. While the media player is sending music to the audio driver,
    the user interface with all its bells and whistles is being constantly
    updated. This is what threads are for -- concurrency within one single
    process.

    So how is concurrency implemented? Parallel work on single core CPUs is an
    illusion which is somewhat similar to the illusion of moving images in
    cinema.
    For processes, the illusion is produced by interrupting the processor's
    work on one process after a very short time. Then the processor moves on to
    the next process. In order to switch between processes, the current program
    counter is saved and the next processor's program counter is loaded. This
    is not sufficient because the same needs to be done with registers and
    certain architecture and OS specific data.

    Just as one CPU can power two or more processes, it is also possible to let
    the CPU run on two different code segments of one single process. When a
    process starts, it always executes one code segment and therefore the
    process is said to have one thread. However, the program may decide to
    start a second thread. Then, two different code sequences are processed
    simultaneously inside one process. Concurrency is achieved on single core
    CPUs by repeatedly saving program counters and registers then loading the
    next thread's program counters and registers. No cooperation from the
    program is required to cycle between the active threads. A thread may be in
    any state when the switch to the next thread occurs.

    The current trend in CPU design is to have several cores. A typical
    single-threaded application can make use of only one core. However, a
    program with multiple threads can be assigned to multiple cores, making
    things happen in a truly concurrent way. As a result, distributing work
    to more than one thread can make a program run much faster on multicore
    CPUs because additional cores can be used.

    \section2 GUI Thread and Worker Thread

    As mentioned, each program has one thread when it is started. This thread
    is called the "main thread" (also known as the "GUI thread" in Qt
    applications). The Qt GUI must run in this thread. All widgets and several
    related classes, for example QPixmap, don't work in secondary threads.
    A secondary thread is commonly referred to as a "worker thread" because it
    is used to offload processing work from the main thread.

    \section2 Simultaneous Access to Data

    Each thread has its own stack, which means each thread has its own call
    history and local variables. Unlike processes, threads share the same
    address space. The following diagram shows how the building blocks of
    threads are located in memory. Program counter and registers of inactive
    threads are typically kept in kernel space. There is a shared copy of the
    code and a separate stack for each thread.

    \image threadvisual-example.png "Thread visualization"

    If two threads have a pointer to the same object, it is possible that both
    threads will access that object at the same time and this can potentially
    destroy the object's integrity. It's easy to imagine the many things that
    can go wrong when two methods of the same object are executed
    simultaneously.

    Sometimes it is necessary to access one object from different threads;
    for example, when objects living in different threads need to communicate.
    Since threads use the same address space, it is easier and faster for
    threads to exchange data than it is for processes. Data does not have to be
    serialized and copied. Passing pointers is possible, but there must be a
    strict coordination of what thread touches which object. Simultaneous
    execution of operations on one object must be prevented. There are several
    ways of achieving this and some of them are described below.

    So what can be done safely? All objects created in a thread can be used
    safely within that thread provided that other threads don't have references
    to them and objects don't have implicit coupling with other threads. Such
    implicit coupling may happen when data is shared between instances as with
    static members, singletons or global data. Familiarize yourself with the
    concept of \l{Reentrancy and Thread-Safety}{thread safe and reentrant}
    classes and functions.

    \section1 Using Threads

    There are basically two use cases for threads:

    \list
    \li Make processing faster by making use of multicore processors.
    \li Keep the GUI thread or other time critical threads responsive by
       offloading long lasting processing or blocking calls to other threads.
    \endlist

    \section2 When to Use Alternatives to Threads

    Developers need to be very careful with threads. It is easy to start other
    threads, but very hard to ensure that all shared data remains consistent.
    Problems are often hard to find because they may only show up once in a
    while or only on specific hardware configurations. Before creating threads
    to solve certain problems, possible alternatives should be considered.

    \table
    \header
        \li Alternative
        \li Comment
    \row
        \li QEventLoop::processEvents()
        \li Calling QEventLoop::processEvents() repeatedly during a
           time-consuming calculation prevents GUI blocking. However, this
           solution doesn't scale well because the call to processEvents() may
           occur too often, or not often enough, depending on hardware.
    \row
        \li QTimer
        \li Background processing can sometimes be done conveniently using a
           timer to schedule execution of a slot at some point in the future.
           A timer with an interval of 0 will time out as soon as there are no
           more events to process.
    \row
        \li QSocketNotifier QNetworkAccessManager QIODevice::readyRead()
        \li This is an alternative to having one or multiple threads, each with
           a blocking read on a slow network connection. As long as the
           calculation in response to a chunk of network data can be executed
           quickly, this reactive design is better than synchronous waiting in
           threads. Reactive design is less error prone and energy efficient
           than threading. In many cases there are also performance benefits.
    \endtable

    In general, it is recommended to only use safe and tested paths and to
    avoid introducing ad-hoc threading concepts. The QtConcurrent module provides an easy
    interface for distributing work to all of the processor's cores. The
    threading code is completely hidden in the QtConcurrent framework, so you
    don't have to take care of the details. However, QtConcurrent can't be used
    when communication with the running thread is needed, and it shouldn't be
    used to handle blocking operations.

    \section2 Which Qt Thread Technology Should You Use?

    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

    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

    As mentioned above, developers must always be careful when calling objects'
    methods from other threads. \l{QObject#Thread Affinity}{Thread affinity}
    does not change this situation.
    Qt documentation marks several methods as thread-safe.
    \l{QCoreApplication::}{postEvent()} is a noteworthy example. A thread-safe
    method may be called from different threads simultaneously.

    In cases where there is usually no concurrent access to methods, calling
    non-thread-safe methods of objects in other threads may work thousands
    of times before a concurrent access occurs, causing unexpected behavior.
    Writing test code does not entirely ensure thread correctness, but it is
    still important.
    On Linux, Valgrind and Helgrind can help detect threading errors.

    \section2 Protecting the Integrity of Data

    When writing a multithread application, extra care must be taken to avoid
    data corruption. See \l{Synchronizing Threads} for a discussion on how to
    use threads safely.

    \section2 Dealing with Asynchronous Execution

    One way to obtain a worker thread's result is by waiting for the thread
    to terminate. In many cases, however, a blocking wait isn't acceptable. The
    alternative to a blocking wait are asynchronous result deliveries with
    either posted events or queued signals and slots. This generates a certain
    overhead because an operation's result does not appear on the next source
    line, but in a slot located somewhere else in the source file. Qt
    developers are used to working with this kind of asynchronous behavior
    because it is much similar to the kind of event-driven programming used in
    GUI applications.

    \section1 Examples

    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

    Threading is a very complicated subject. Qt offers more classes for
    threading than we have presented in this tutorial. The following materials
    can help you go into the subject in more depth:

    \list
    \li Good video tutorials about threads with Qt can be found in the material
       from the \l{Training Day at Qt Developer Days 2009}.
    \li The \l{Thread Support in Qt} document is a good starting point into
       the reference documentation.
    \li Qt comes with several additional examples for
       \l{Threading and Concurrent Programming Examples}{QThread and QtConcurrent}.
    \li Several good books describe how to work with Qt threads. The most
       extensive coverage can be found in \e{Advanced Qt Programming} by Mark
       Summerfield, Prentice Hall - roughly 70 of 500 pages cover QThread and
       QtConcurrent.
    \endlist
*/