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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
|
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page threads.html
\title Thread Support in Qt
\ingroup architecture
\brief A detailed discussion of thread handling in Qt.
Qt provides thread support in the form of platform-independent
threading classes, a thread-safe way of posting events, and
signal-slot connections across threads. This makes it easy to
develop portable multithreaded Qt applications and take advantage
of multiprocessor machines. Multithreaded programming is also a
useful paradigm for performing time-consuming operations without
freezing the user interface of an application.
Earlier versions of Qt offered an option to build the library
without thread support. Since Qt 4.0, threads are always enabled.
This document is intended for an audience that has knowledge of,
and experience with, multithreaded applications. If you are new
to threading see our \l{#reading}{Recommended Reading} list.
Topics:
\tableofcontents
\section1 The Threading Classes
Qt includes the following thread classes:
\list
\o QThread provides the means to start a new thread.
\o QThreadStorage provides per-thread data storage.
\o QThreadPool manages a pool of threads that run QRunnable objects.
\o QRunnable is an abstract class representing a runnable object.
\o QMutex provides a mutual exclusion lock, or mutex.
\o QMutexLocker is a convenience class that automatically locks
and unlocks a QMutex.
\o QReadWriteLock provides a lock that allows simultaneous read access.
\o QReadLocker and QWriteLocker are convenience classes that automatically
lock and unlock a QReadWriteLock.
\o QSemaphore provides an integer semaphore (a generalization of a mutex).
\o QWaitCondition provides a way for threads to go to sleep until
woken up by another thread.
\o QAtomicInt provides atomic operations on integers.
\o QAtomicPointer provides atomic operations on pointers.
\endlist
\note Qt's threading classes are implemented with native threading APIs;
e.g., Win32 and pthreads. Therefore, they can be used with threads of the
same native API.
\section2 Creating a Thread
To create a thread, subclass QThread and reimplement its
\l{QThread::run()}{run()} function. For example:
\snippet doc/src/snippets/threads/threads.h 0
\codeline
\snippet doc/src/snippets/threads/threads.cpp 0
\snippet doc/src/snippets/threads/threads.cpp 1
\dots
\snippet doc/src/snippets/threads/threads.cpp 2
Then, create an instance of the thread object and call
QThread::start(). 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.
In addition, you must create the QApplication (or
QCoreApplication) object before you can create a QThread.
\section2 Synchronizing Threads
The QMutex, QReadWriteLock, QSemaphore, and QWaitCondition
classes provide means to synchronize threads. While the main idea
with threads is that they should be as concurrent as possible,
there are points where threads must stop and wait for other
threads. For example, if two threads try to access the same
global variable simultaneously, the results are usually
undefined.
QMutex provides a mutually exclusive lock, or mutex. At most one
thread can hold the mutex at any time. If a thread tries to
acquire the mutex while the mutex is already locked, the thread will
be put to sleep until the thread that currently holds the mutex
unlocks it. Mutexes are often used to protect accesses to shared
data (i.e., data that can be accessed from multiple threads
simultaneously). In the \l{Reentrancy and Thread-Safety} section
below, we will use it to make a class thread-safe.
QReadWriteLock is similar to QMutex, except that it distinguishes
between "read" and "write" access to shared data and allows
multiple readers to access the data simultaneously. Using
QReadWriteLock instead of QMutex when it is possible can make
multithreaded programs more concurrent.
QSemaphore is a generalization of QMutex that protects a certain
number of identical resources. In contrast, a mutex protects
exactly one resource. The \l{threads/semaphores}{Semaphores}
example shows a typical application of semaphores: synchronizing
access to a circular buffer between a producer and a consumer.
QWaitCondition allows a thread to wake up other threads when some
condition has been met. One or many threads can block waiting for
a QWaitCondition to set a condition with
\l{QWaitCondition::wakeOne()}{wakeOne()} or
\l{QWaitCondition::wakeAll()}{wakeAll()}. Use
\l{QWaitCondition::wakeOne()}{wakeOne()} to wake one randomly
selected event or \l{QWaitCondition::wakeAll()}{wakeAll()} to
wake them all. The \l{threads/waitconditions}{Wait Conditions}
example shows how to solve the producer-consumer problem using
QWaitCondition instead of QSemaphore.
Note that Qt's synchronization classes rely on the use of properly
aligned pointers. For instance, you cannot use packed classes with
MSVC.
\target qtconcurrent intro
\section1 QtConcurrent
The QtConcurrent namespace provides high-level APIs that make it
possible to write multi-threaded programs without using low-level
threading primitives such as mutexes, read-write locks, wait
conditions, or semaphores. Programs written with QtConcurrent
automatically adjust the number of threads used according to the
number of processor cores available. This means that applications
written today will continue to scale when deployed on multi-core
systems in the future.
QtConcurrent includes functional programming style APIs for
parallel list processing, including a MapReduce and FilterReduce
implementation for shared-memory (non-distributed) systems, and
classes for managing asynchronous computations in GUI
applications:
\list
\o QtConcurrent::map() applies a function to every item in a container,
modifying the items in-place.
\o QtConcurrent::mapped() is like map(), except that it returns a new
container with the modifications.
\o QtConcurrent::mappedReduced() is like mapped(), except that the
modified results are reduced or folded into a single result.
\o QtConcurrent::filter() removes all items from a container based on the
result of a filter function.
\o QtConcurrent::filtered() is like filter(), except that it returns a new
container with the filtered results.
\o QtConcurrent::filteredReduced() is like filtered(), except that the
filtered results are reduced or folded into a single result.
\o QtConcurrent::run() runs a function in another thread.
\o QFuture represents the result of an asynchronous computation.
\o QFutureIterator allows iterating through results available via QFuture.
\o QFutureWatcher allows monitoring a QFuture using signals-and-slots.
\o QFutureSynchronizer is a convenience class that automatically
synchronizes several QFutures.
\endlist
Qt Concurrent supports several STL-compatible container and iterator types,
but works best with Qt containers that have random-access iterators, such as
QList or QVector. The map and filter functions accept both containers and begin/end iterators.
STL Iterator support overview:
\table
\header
\o Iterator Type
\o Example classes
\o Support status
\row
\o Input Iterator
\o
\o Not Supported
\row
\o Output Iterator
\o
\o Not Supported
\row
\o Forward Iterator
\o std::slist
\o Supported
\row
\o Bidirectional Iterator
\o QLinkedList, std::list
\o Supported
\row
\o Random Access Iterator
\o QList, QVector, std::vector
\o Supported and Recommended
\endtable
Random access iterators can be faster in cases where Qt Concurrent is iterating
over a large number of lightweight items, since they allow skipping to any point
in the container. In addition, using random access iterators allows Qt Concurrent
to provide progress information trough QFuture::progressValue() and QFutureWatcher::
progressValueChanged().
The non in-place modifying functions such as mapped() and filtered() makes a
copy of the container when called. If you are using STL containers this copy operation
might take some time, in this case we recommend specifying the begin and end iterators
for the container instead.
\keyword reentrant
\keyword thread-safe
\section1 Reentrancy and Thread-Safety
Throughout the Qt documentation, the terms \e reentrant and \e
thread-safe are used to specify how a function can be used in
multithreaded applications:
\list
\o A \e reentrant function can be called simultaneously by
multiple threads provided that each invocation of the function
references unique data.
\o A \e thread-safe function can be called simultaneously by
multiple threads when each invocation references shared data.
All access to the shared data is serialized.
\endlist
By extension, a class is said to be reentrant if each and every
one of its functions can be called simultaneously by multiple
threads on different instances of the class. Similarly, the class
is said to be thread-safe if the functions can be called by
different threads on the same instance.
Classes in the documentation will be documented as thread-safe only
if they are intended to be used by multiple threads.
Note that the terminology in this domain isn't entirely
standardized. POSIX uses a somewhat different definition of
reentrancy and thread-safety for its C APIs. When dealing with an
object-oriented C++ class library such as Qt, the definitions
must be adapted.
Most C++ classes are inherently reentrant, since they typically
only reference member data. Any thread can call such a member
function on an instance of the class, as long as no other thread
is calling a member function on the same instance. For example,
the \c Counter class below is reentrant:
\snippet doc/src/snippets/threads/threads.cpp 3
\snippet doc/src/snippets/threads/threads.cpp 4
The class isn't thread-safe, because if multiple threads try to
modify the data member \c n, the result is undefined. This is
because C++'s \c ++ and \c -- operators aren't necessarily
atomic. Indeed, they usually expand to three machine
instructions:
\list 1
\o Load the variable's value in a register.
\o Increment or decrement the register's value.
\o Store the register's value back into main memory.
\endlist
If thread A and thread B load the variable's old value
simultaneously, increment their register, and store it back, they
end up overwriting each other, and the variable is incremented
only once!
Clearly, the access must be serialized: Thread A must perform
steps 1, 2, 3 without interruption (atomically) before thread B
can perform the same steps; or vice versa. An easy way to make
the class thread-safe is to protect all access to the data
members with a QMutex:
\snippet doc/src/snippets/threads/threads.cpp 5
\snippet doc/src/snippets/threads/threads.cpp 6
The QMutexLocker class automatically locks the mutex in its
constructor and unlocks it when the destructor is invoked, at the
end of the function. Locking the mutex ensures that access from
different threads will be serialized. The \c mutex data member is
declared with the \c mutable qualifier because we need to lock
and unlock the mutex in \c value(), which is a const function.
Most Qt classes are reentrant and not thread-safe, to avoid the
overhead of repeatedly locking and unlocking a QMutex. For
example, QString is reentrant, meaning that you can use it in
different threads, but you can't access the same QString object
from different threads simultaneously (unless you protect it with
a mutex yourself). A few classes and functions are thread-safe;
these are mainly thread-related classes such as QMutex, or
fundamental functions such as QCoreApplication::postEvent().
\section1 Threads and QObjects
QThread inherits QObject. It emits signals to indicate that the
thread started or finished executing, and provides a few slots as
well.
More interesting is that \l{QObject}s can be used in multiple
threads, emit signals that invoke slots in other threads, and
post events to objects that "live" in other threads. This is
possible because each thread is allowed to have its own event
loop.
\section2 QObject Reentrancy
QObject is reentrant. Most of its non-GUI subclasses, such as
QTimer, QTcpSocket, QUdpSocket, QHttp, QFtp, and QProcess, are
also reentrant, making it possible to use these classes from
multiple threads simultaneously. Note that these classes are
designed to be created and used from within a single thread;
creating an object in one thread and calling its functions from
another thread is not guaranteed to work. There are three
constraints to be aware of:
\list
\o \e{The child of a QObject must always be created in the thread
where the parent was created.} This implies, among other
things, that you should never pass the QThread object (\c
this) as the parent of an object created in the thread (since
the QThread object itself was created in another thread).
\o \e{Event driven objects may only be used in a single thread.}
Specifically, this applies to the \l{timers.html}{timer
mechanism} and the \l{QtNetwork}{network module}. For example,
you cannot start a timer or connect a socket in a thread that
is not the \l{QObject::thread()}{object's thread}.
\o \e{You must ensure that all objects created in a thread are
deleted before you delete the QThread.} This can be done
easily by creating the objects on the stack in your
\l{QThread::run()}{run()} implementation.
\endlist
Although QObject is reentrant, the GUI classes, notably QWidget
and all its subclasses, are not reentrant. They can only be used
from the main thread. As noted earlier, QCoreApplication::exec()
must also be called from that thread.
In practice, the impossibility of using GUI classes in other
threads than the main thread can easily be worked around by
putting time-consuming operations in a separate worker thread and
displaying the results on screen in the main thread when the
worker thread is finished. This is the approach used for
implementing the \l{threads/mandelbrot}{Mandelbrot} and
the \l{network/blockingfortuneclient}{Blocking Fortune Client}
example.
\section2 Per-Thread Event Loop
Each thread can have its own event loop. The initial thread
starts its event loops using QCoreApplication::exec(); other
threads can start an event loop using QThread::exec(). Like
QCoreApplication, QThread provides an
\l{QThread::exit()}{exit(int)} function and a
\l{QThread::quit()}{quit()} slot.
An event loop in a thread makes it possible for the thread to use
certain non-GUI Qt classes that require the presence of an event
loop (such as QTimer, QTcpSocket, and QProcess). It also makes it
possible to connect signals from any threads to slots of a
specific thread. This is explained in more detail in the
\l{Signals and Slots Across Threads} section below.
\image threadsandobjects.png Threads, objects, and event loops
A QObject instance is said to \e live in the thread in which it
is created. Events to that object are dispatched by that thread's
event loop. The thread in which a QObject lives is available using
QObject::thread().
Note that for QObjects that are created before QApplication,
QObject::thread() returns zero. This means that the main thread
will only handle posted events for these objects; other event
processing is not done at all for objects with no thread. Use the
QObject::moveToThread() function to change the thread affinity for
an object and its children (the object cannot be moved if it has a
parent).
Calling \c delete on a QObject from another thread than the
thread where it is created (or accessing the object in other
ways) is unsafe unless you can guarantee that the object isn't
processing events at the same moment. Use QObject::deleteLater()
instead; it will post a
\l{QEvent::DeferredDelete}{DeferredDelete} event, which the
event loop of the object's thread will eventually pick up.
If no event loop is running, events won't be delivered to the
object. For example, if you create a QTimer object in a thread
but never call \l{QThread::exec()}{exec()}, the QTimer will never emit its
\l{QTimer::timeout()}{timeout()} signal. Calling
\l{QObject::deleteLater()}{deleteLater()} won't work either. (These
restrictions apply to the main thread as well.)
You can manually post events to any object in any thread at any
time using the thread-safe function
QCoreApplication::postEvent(). The events will automatically be
dispatched by the event loop of the thread where the object was
created.
Event filters are supported in all threads, with the restriction
that the monitoring object must live in the same thread as the
monitored object. Similarly, QCoreApplication::sendEvent()
(unlike \l{QCoreApplication::postEvent()}{postEvent()}) can only
be used to dispatch events to objects living in the thread from
which the function is called.
\section2 Accessing QObject Subclasses from Other Threads
QObject and all of its subclasses are not thread-safe. This
includes the entire event delivery system. It is important to keep
in mind that the event loop may be delivering events to your
QObject subclass while you are accessing the object from another
thread.
If you are calling a function on an QObject subclass that doesn't
live in the current thread and the object might receive events,
you must protect all access to your QObject subclass's internal
data with a mutex; otherwise, you may experience crashes or other
undesired behavior.
Like other objects, QThread objects live in the thread where the
object was created -- \e not in the thread that is created when
QThread::run() is called. It is generally unsafe to provide slots
in your QThread subclass, unless you protect the member variables
with a mutex.
On the other hand, you can safely emit signals from your
QThread::run() implementation, because signal emission is
thread-safe.
\section2 Signals and Slots Across Threads
Qt supports three types of signal-slot connections:
\list
\o With \l{Qt::DirectConnection}{direct connections}, the
slot gets called immediately when the signal is emitted. The
slot is executed in the thread that emitted the signal (which
is not necessarily the thread where the receiver object
lives).
\o With \l{Qt::QueuedConnection}{queued connections}, the
slot is invoked when control returns to the event loop of the
thread to which the object belongs. The slot is executed in
the thread where the receiver object lives.
\o With \l{Qt::AutoConnection}{auto connections} (the default),
the behavior is the same as with direct connections if
the signal is emitted in the thread where the receiver lives;
otherwise, the behavior is that of a queued connection.
\endlist
The connection type can be specified by passing an additional
argument to \l{QObject::connect()}{connect()}. Be aware that
using direct connections when the sender and receiver live in
different threads is unsafe if an event loop is running in the
receiver's thread, for the same reason that calling any function
on an object living in another thread is unsafe.
QObject::connect() itself is thread-safe.
The \l{threads/mandelbrot}{Mandelbrot} example uses a queued
connection to communicate between a worker thread and the main
thread. To avoid freezing the main thread's event loop (and, as a
consequence, the application's user interface), all the
Mandelbrot fractal computation is done in a separate worker
thread. The thread emits a signal when it is done rendering the
fractal.
Similarly, the \l{network/blockingfortuneclient}{Blocking Fortune
Client} example uses a separate thread for communicating with
a TCP server asynchronously.
\section1 Threads and Implicit Sharing
Qt uses an optimization called \l{implicit sharing} for many of
its value class, notably QImage and QString. Beginning with Qt 4,
implicit shared classes can safely be copied across threads, like
any other value classes. They are fully
\l{#reentrant}{reentrant}. The implicit sharing is really
\e implicit.
In many people's minds, implicit sharing and multithreading are
incompatible concepts, because of the way the reference counting
is typically done. Qt, however, uses atomic reference counting to
ensure the integrity of the shared data, avoiding potential
corruption of the reference counter.
Note that atomic reference counting does not guarantee
\l{#thread-safe}{thread-safety}. Proper locking should be used
when sharing an instance of an implicitly shared class between
threads. This is the same requirement placed on all
\l{#reentrant}{reentrant} classes, shared or not. Atomic reference
counting does, however, guarantee that a thread working on its
own, local instance of an implicitly shared class is safe. We
recommend using \l{Signals and Slots Across Threads}{signals and
slots} to pass data between threads, as this can be done without
the need for any explicit locking.
To sum it up, implicitly shared classes in Qt 4 are really \e
implicitly shared. Even in multithreaded applications, you can
safely use them as if they were plain, non-shared, reentrant
value-based classes.
\section1 Threads and the SQL Module
A connection can only be used from within the thread that created it.
Moving connections between threads or creating queries from a different
thread is not supported.
In addition, the third party libraries used by the QSqlDrivers can impose
further restrictions on using the SQL Module in a multithreaded program.
Consult the manual of your database client for more information
\section1 Painting in Threads
QPainter can be used to paint onto QImage, QPrinter, and QPicture
paint devices. Painting onto QPixmaps and QWidgets is \e not
supported. On Mac OS X the automatic progress dialog will not be
displayed if you are printing from outside the GUI thread.
Any number of threads can paint at any given time, however only
one thread at a time can paint on a given paint device. In other
words, two threads can paint at the same time if each paints onto
separate QImages, but the two threads cannot paint onto the same
QImage at the same time.
Note that on X11 systems without FontConfig support, Qt cannot
render text outside of the GUI thread. You can use the
QFontDatabase::supportsThreadedFontRendering() function to detect
whether or not font rendering can be used outside the GUI thread.
\section1 Threads and Rich Text Processing
The QTextDocument, QTextCursor, and \link richtext.html all
related classes\endlink are reentrant.
Note that a QTextDocument instance created in the GUI thread may
contain QPixmap image resources. Use QTextDocument::clone() to
create a copy of the document, and pass the copy to another thread for
further processing (such as printing).
\section1 Threads and the SVG module
The QSvgGenerator and QSvgRenderer classes in the QtSvg module
are reentrant.
\target reading
\section1 Recommended Reading
\list
\o \l{Threads Primer: A Guide to Multithreaded Programming}
\o \l{Thread Time: The Multithreaded Programming Guide}
\o \l{Pthreads Programming: A POSIX Standard for Better Multiprocessing}
\o \l{Win32 Multithreaded Programming}
\endlist
*/
|