summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSze Howe Koh <szehowe.koh@gmail.com>2013-11-07 00:24:20 +0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-08 16:45:26 +0100
commit706eeadf3aa226ea02496c352006b26abe791f07 (patch)
tree1f743087487f44dc74b843f8d1fb2b5fdf1a1938 /src
parent8647bac9cff4240c2e75fd978a9c21329ca4e214 (diff)
Doc: Move threading overviews from qtbase.git to qtdoc.git
- This topic is relevant to multiple modules, as illustrated by the "Thread-Support in Qt Modules" page. Multithreading can be done in both C++ and QML. - Moving also fixes links to QML-related pages. - Snippets are copied, not moved. QThreadStorage docs need them. - QDoc: "DEPENDS += qtdoc" added to keep the "\reentrant" command working. It creates a link to the "reentrant" keyword. Change-Id: I2cdf6139e62d66911561c30fcca7aab160a694b1 Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/doc/images/threadsandobjects.pngbin66096 -> 0 bytes
-rw-r--r--src/corelib/doc/images/threadvisual-example.pngbin16823 -> 0 bytes
-rw-r--r--src/corelib/doc/src/threads-basics.qdoc244
-rw-r--r--src/corelib/doc/src/threads.qdoc828
-rw-r--r--src/xml/doc/qtxml.qdocconf2
5 files changed, 1 insertions, 1073 deletions
diff --git a/src/corelib/doc/images/threadsandobjects.png b/src/corelib/doc/images/threadsandobjects.png
deleted file mode 100644
index 8357d2532a..0000000000
--- a/src/corelib/doc/images/threadsandobjects.png
+++ /dev/null
Binary files differ
diff --git a/src/corelib/doc/images/threadvisual-example.png b/src/corelib/doc/images/threadvisual-example.png
deleted file mode 100644
index 2a49874719..0000000000
--- a/src/corelib/doc/images/threadvisual-example.png
+++ /dev/null
Binary files differ
diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc
deleted file mode 100644
index 2206899460..0000000000
--- a/src/corelib/doc/src/threads-basics.qdoc
+++ /dev/null
@@ -1,244 +0,0 @@
-/****************************************************************************
-**
-** 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
-*/
diff --git a/src/corelib/doc/src/threads.qdoc b/src/corelib/doc/src/threads.qdoc
deleted file mode 100644
index efed33106a..0000000000
--- a/src/corelib/doc/src/threads.qdoc
+++ /dev/null
@@ -1,828 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-/*!
- \group thread
- \title Threading Classes
-
- These \l{Qt Core} classes provide threading support to applications.
- The \l{Thread Support in Qt} page covers how to use these classes.
-*/
-
-/*!
- \page threads.html
- \title Thread Support in Qt
- \ingroup qt-basic-concepts
- \brief A detailed discussion of thread handling in Qt.
-
- \ingroup frameworks-technologies
-
- \nextpage Multithreading Technologies 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.
-
- \section1 Topics:
-
- \list
- \li \l{Recommended Reading}
- \li \l{The Threading Classes}
- \li \l{Multithreading Technologies in Qt}
- \li \l{Synchronizing Threads}
- \li \l{Reentrancy and Thread-Safety}
- \li \l{Threads and QObjects}
- \li \l{Thread-Support in Qt Modules}
- \endlist
-
- \section1 Recommended Reading
-
- This document is intended for an audience that has knowledge of,
- and experience with, multithreaded applications. If you are new
- to threading see our Recommended Reading list:
-
- \list
- \li \l {http://www.amazon.com/Threads-Primer-Guide-Multithreaded-Programming/dp/0134436989}{Threads Primer: A Guide to Multithreaded Programming}
- \li \l {http://www.amazon.com/Thread-Time-MultiThreaded-Programming-Guide/dp/0131900676}{Thread Time: The Multithreaded Programming Guide}
- \li \l {http://www.amazon.com/Pthreads-Programming-Standard-Multiprocessing-Nutshell/dp/1565921151a}{Pthreads Programming: A POSIX Standard for Better Multiprocessing}
- \li \l {http://www.amazon.com/WIN32-Multithreaded-Programming-Aaron-Cohen/dp/1565922964}{Win32 Multithreaded Programming}
- \endlist
-
- \section1 The Threading Classes
-
- These classes are relevant to threaded applications.
-
- \annotatedlist thread
-
-\omit
- \list
- \li QThread provides the means to start a new thread.
- \li QThreadStorage provides per-thread data storage.
- \li QThreadPool manages a pool of threads that run QRunnable objects.
- \li QRunnable is an abstract class representing a runnable object.
- \li QMutex provides a mutual exclusion lock, or mutex.
- \li QMutexLocker is a convenience class that automatically locks
- and unlocks a QMutex.
- \li QReadWriteLock provides a lock that allows simultaneous read access.
- \li QReadLocker and QWriteLocker are convenience classes that automatically
- lock and unlock a QReadWriteLock.
- \li QSemaphore provides an integer semaphore (a generalization of a mutex).
- \li QWaitCondition provides a way for threads to go to sleep until
- woken up by another thread.
- \li QAtomicInt provides atomic operations on integers.
- \li QAtomicPointer provides atomic operations on pointers.
- \endlist
-\endomit
-
- \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.
-*/
-
-/*!
- \page threads-technologies.html
- \title Multithreading Technologies in Qt
- \ingroup qt-basic-concepts
- \brief An overview and comparison of different ways to use threads in Qt.
-
- \ingroup frameworks-technologies
-
- \contentspage Thread Support in Qt
- \previouspage Thread Support in Qt
- \nextpage Synchronizing Threads
-
- Qt offers many classes and functions for working with threads. Below are
- four different approaches that Qt programmers can use to implement
- multithreaded applications.
-
-
- \section1 QThread: Low-Level API with Optional Event Loops
-
- QThread is the foundation of all thread control in Qt. Each QThread
- instance represents and controls one thread.
-
- QThread can either be instantiated directly or subclassed. Instantiating a
- QThread provides a parallel event loop, allowing QObject slots to be invoked
- in a secondary thread. Subclassing a QThread allows the application to initialize
- the new thread before starting its event loop, or to run parallel code
- without an event loop.
-
- See the \l{QThread}{QThread class reference} and the \l{Threading and
- Concurrent Programming Examples}{threading examples} for demonstrations on
- how to use QThread.
-
-
- \section1 QThreadPool and QRunnable: Reusing Threads
-
- Creating and destroying threads frequently can be expensive. To reduce this
- overhead, existing threads can be reused for new tasks. QThreadPool is a
- collection of reuseable QThreads.
-
- To run code in one of a QThreadPool's threads, reimplement QRunnable::run()
- and instantiate the subclassed QRunnable. Use QThreadPool::start() to put
- the QRunnable in the QThreadPool's run queue. When a thread becomes available,
- the code within QRunnable::run() will execute in that thread.
-
- Each Qt application has a global thread pool, which is accessible through
- QThreadPool::globalInstance(). This global thread pool automatically maintains
- an optimal number of threads based on the number of cores in the CPU. However,
- a separate QThreadPool can be created and managed explicitly.
-
-
- \section1 Qt Concurrent: Using a High-level API
-
- The \l{Qt Concurrent} module provides high-level functions that deal with some
- common parallel computation patterns: map, filter, and reduce. Unlike using
- QThread and QRunnable, these functions never require the use of \l{Synchronizing
- Threads#Low-Level Synchronization Primitives}{low-level threading primitives}
- such as mutexes or semaphores. Instead, they return a QFuture object which can
- be used to retrieve the functions' results when they are ready. QFuture can
- also be used to query computation progress and to pause/resume/cancel the
- computation. For convenience, QFutureWatcher enables interactions with
- \l{QFuture}s via signals and slots.
-
- \l{Qt Concurrent}'s map, filter and reduce algorithms automatically distribute
- computation across all available processor cores, so applications written today
- will continue to scale when deployed later on a system with more cores.
-
- This module also provides the QtConcurrent::run() function, which can run any
- function in another thread. However, QtConcurrent::run() only supports a subset
- of features available to the map, filter and reduce functions. The QFuture
- can be used to retrieve the function's return value and to check if the thread
- is running. However, a call to QtConcurrent::run() uses one thread only, cannot
- be paused/resumed/canceled, and cannot be queried for progress.
-
- See the \l{Qt Concurrent} module documentation for details on the individual functions.
-
-
- \section1 WorkerScript: Threading in QML
-
- The WorkerScript QML type lets JavaScript code run in parallel with the GUI
- thread.
-
- Each WorkerScript instance can have one \c{.js} script attached to it. When
- WorkerScript::sendMessage() is called, the script will run in a separate thread
- (and a separate \l{QQmlContext}{QML context}). When the script finishes
- running, it can send a reply back to the GUI thread which will invoke the
- WorkerScript::onMessage() signal handler.
-
- Using a WorkerScript is similar to using a worker QObject that has been moved
- to another thread. Data is transferred between threads via signals.
-
- See the WorkerScript documentation for details on how to implement the script,
- and for a list of data types that can be passed between threads.
-
-
- \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
- \li Feature
- \li QThread
- \li QRunnable and QThreadPool
- \li QtConcurrent::run()
- \li Qt Concurrent (Map, Filter, Reduce)
- \li WorkerScript
- \row
- \li API
- \li C++
- \li C++
- \li C++
- \li C++
- \li QML
- \row
- \li Thread priority can be specified
- \li Yes
- \li Yes
- \li
- \li
- \li
- \row
- \li Thread can run an event loop
- \li Yes
- \li
- \li
- \li
- \li
- \row
- \li Thread can receive data updates through signals
- \li Yes (received by a worker QObject)
- \li
- \li
- \li
- \li Yes (received by WorkerScript)
- \row
- \li Thread can be controlled using signals
- \li Yes (received by QThread)
- \li
- \li
- \li Yes (received by QFutureWatcher)
- \li
- \row
- \li Thread can be monitored through a QFuture
- \li
- \li
- \li Partially
- \li Yes
- \li
- \row
- \li Built-in ability to pause/resume/cancel
- \li
- \li
- \li
- \li Yes
- \li
- \endtable
-
-
- \section2 Example Use Cases
-
- \table
- \header
- \li Lifetime of thread
- \li Operation
- \li Solution
- \row
- \li One call
- \li Run a new 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 Run an existing function within another thread and get its return value.
- \li Run the function using QtConcurrent::run(). Have a QFutureWatcher emit
- the \l{QFutureWatcher::}{finished()} signal when the function has
- returned, and call QFutureWatcher::result() to get the function's return
- value.
- \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::}{filteredReduced()} and
- \l{QtConcurrent::}{mappedReduced()} instead.
- \row
- \li One call/Permanent
- \li Perfrom a long computation in a pure QML application, and update the GUI
- when the results are ready.
- \li Place the computation code in a \c{.js} script and attach it to a
- WorkerScript instance. Call \l{WorkerScript::}{sendMessage()} to start the
- computation in a new thread. Let the script call WorkerScript::sendMessage()
- too, to pass the result back to the GUI thread. Handle the result in
- \l{WorkerScript::}{onMessage} and update the GUI there.
- \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
-*/
-
-/*!
- \page threads-synchronizing.html
- \title Synchronizing Threads
-
- \previouspage Multithreading Technologies in Qt
- \contentspage Thread Support in Qt
- \nextpage Reentrancy and Thread-Safety
-
- While the purpose of threads is to allow code to run in parallel,
- there are times where threads must stop and wait for other
- threads. For example, if two threads try to write to the same
- variable simultaneously, the result is undefined. The principle of
- forcing threads to wait for one another is called \e{mutual exclusion}.
- It is a common technique for protecting shared resources such as data.
-
- Qt provides low-level primitives as well as high-level mechanisms
- for synchronizing threads.
-
- \section1 Low-Level Synchronization Primitives
-
- QMutex is the basic class for enforcing mutual exclusion. A thread
- locks a mutex in order to gain access to a shared resource. If a second
- thread tries to lock the mutex while it is already locked, the second
- thread will be put to sleep until the first thread completes its task
- and unlocks the mutex.
-
- QReadWriteLock is similar to QMutex, except that it distinguishes
- between "read" and "write" access. When a piece of data is not being
- written to, it is safe for multiple threads to read from it simultaneously.
- A QMutex forces multiple readers to take turns to read shared data, but a
- QReadWriteLock allows simultaneous reading, thus improving parallelism.
-
- QSemaphore is a generalization of QMutex that protects a certain
- number of identical resources. In contrast, a QMutex protects
- exactly one resource. The \l{Semaphores Example} shows a typical application
- of semaphores: synchronizing access to a circular buffer between a producer
- and a consumer.
-
- QWaitCondition synchronizes threads not by enforcing mutual exclusion but by
- providing a \e{condition variable}. While the other primitives make threads
- wait until a resource is unlocked, QWaitCondition makes threads wait until a
- particular condition has been met. To allow the waiting threads to proceed,
- call \l{QWaitCondition::wakeOne()}{wakeOne()} to wake one randomly
- selected thread or \l{QWaitCondition::wakeAll()}{wakeAll()} to wake them all
- simultaneously. The \l{Wait Conditions Example} shows how to solve the
- producer-consumer problem using QWaitCondition instead of QSemaphore.
-
- \note Qt's synchronization classes rely on the use of properly
- aligned pointers. For instance, you cannot use packed classes with
- MSVC.
-
- These synchronization classes can be used to make a method thread safe.
- However, doing so incurs a performance penalty, which is why most Qt methods
- are not made thread safe.
-
- \section2 Risks
-
- If a thread locks a resource but does not unlock it, the application may
- freeze because the resource will become permanently unavailable to other threads.
- This can happen, for example, if an exception is thrown and forces the current
- function to return without releasing its lock.
-
- Another similar scenario is a \e{deadlock}. For example, suppose that
- thread A is waiting for thread B to unlock a resource. If thread B is also
- waiting for thread A to unlock a different resource, then both threads will
- end up waiting forever, so the application will freeze.
-
- \section2 Convenience classes
-
- QMutexLocker, QReadLocker and QWriteLocker are convenience classes that make it
- easier to use QMutex and QReadWriteLock. They lock a resource when they are
- constructed, and automatically unlock it when they are destroyed. They are
- designed to simplify code that use QMutex and QReadWriteLock, thus reducing
- the chances that a resource becomes permanently locked by accident.
-
- \section1 High-Level Event Queues
-
- Qt's \l{The Event System}{event system} is very useful for inter-thread
- communication. Every thread may have its own event loop. To call a slot (or
- any \l{Q_INVOKABLE}{invokable} method) in another thread, place that call in
- the target thread's event loop. This lets the target thread finish its current
- task before the slot starts running, while the original thread continues
- running in parallel.
-
- To place an invocation in an event loop, make a queued \l{Signals & Slots}
- {signal-slot} connection. Whenever the signal is emitted, its arguments will
- be recorded by the event system. The thread that the signal receiver
- \l{QObject#Thread Affinity}{lives in} will then run the slot. Alternatively,
- call QMetaObject::invokeMethod() to achieve the same effect without signals.
- In both cases, a \l{Qt::QueuedConnection}{queued connection} must be used
- because a \l{Qt::DirectConnection}{direct connection} bypasses the event
- system and runs the method immediately in the current thread.
-
- There is no risk of deadlocks when using the event system for thread
- synchronization, unlike using low-level primitives. However, the event system
- does not enforce mutual exclusion. If invokable methods access shared data,
- they must still be protected with low-level primitives.
-
- Having said that, Qt's event system, along with \l{Implicit Sharing}{implicitly
- shared} data structures, offers an alternative to traditional thread locking.
- If signals and slots are used exclusively and no variables are shared between
- threads, a multithreaded program can do without low-level primitives altogether.
-
- \sa QThread::exec(), {Threads and QObjects}
-*/
-
-/*!
- \page threads-reentrancy.html
- \title Reentrancy and Thread-Safety
-
- \keyword reentrant
- \keyword thread-safe
-
- \previouspage Synchronizing Threads
- \contentspage Thread Support in Qt
- \nextpage Threads and QObjects
-
- Throughout the documentation, the terms \e{reentrant} and
- \e{thread-safe} are used to mark classes and functions to indicate
- how they can be used in multithread applications:
-
- \list
- \li A \e thread-safe function can be called simultaneously from
- multiple threads, even when the invocations use shared data,
- because all references to the shared data are serialized.
- \li A \e reentrant function can also be called simultaneously from
- multiple threads, but only if each invocation uses its own data.
- \endlist
-
- Hence, a \e{thread-safe} function is always \e{reentrant}, but a
- \e{reentrant} function is not always \e{thread-safe}.
-
- By extension, a class is said to be \e{reentrant} if its member
- functions can be called safely from multiple threads, as long as
- each thread uses a \e{different} instance of the class. The class
- is \e{thread-safe} if its member functions can be called safely
- from multiple threads, even if all the threads use the \e{same}
- instance of the class.
-
- \note Qt classes are only documented as \e{thread-safe} if they
- are intended to be used by multiple threads. If a function is not
- marked as thread-safe or reentrant, it should not be used from
- different threads. If a class is not marked as thread-safe or
- reentrant then a specific instance of that class should not be
- accessed from different threads.
-
- \section1 Reentrancy
-
- C++ classes are often reentrant, simply because they only access
- their own member data. Any thread can call a member function on an
- instance of a reentrant class, as long as no other thread can call
- a member function on the \e{same} instance of the class at the
- same time. For example, the \c Counter class below is reentrant:
-
- \snippet threads/threads.cpp 3
- \snippet 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 the \c ++ and \c -- operators aren't always atomic.
- Indeed, they usually expand to three machine instructions:
-
- \list 1
- \li Load the variable's value in a register.
- \li Increment or decrement the register's value.
- \li 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!
-
- \section1 Thread-Safety
-
- 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 threads/threads.cpp 5
- \snippet 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.
-
- \section1 Notes on Qt Classes
-
- Many Qt classes are \e{reentrant}, but they are not made
- \e{thread-safe}, because making them thread-safe would incur the
- extra overhead of repeatedly locking and unlocking a QMutex. For
- example, QString is reentrant but not thread-safe. You can safely
- access \e{different} instances of QString from multiple threads
- simultaneously, but you can't safely access the \e{same} instance
- of QString from multiple threads simultaneously (unless you
- protect the accesses yourself with a QMutex).
-
- Some Qt classes and functions are thread-safe. These are mainly
- the thread-related classes (e.g. QMutex) and fundamental functions
- (e.g. QCoreApplication::postEvent()).
-
- \note Terminology in the multithreading domain isn't entirely
- standardized. POSIX uses definitions of reentrant and thread-safe
- that are somewhat different for its C APIs. When using other
- object-oriented C++ class libraries with Qt, be sure the
- definitions are understood.
-*/
-
-/*!
- \page threads-qobject.html
- \title Threads and QObjects
-
- \previouspage Reentrancy and Thread Safety
- \contentspage Thread Support in Qt
- \nextpage Thread-Support in Qt Modules
-
- 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.
-
- \section1 QObject Reentrancy
-
- QObject is reentrant. Most of its non-GUI subclasses, such as
- QTimer, QTcpSocket, QUdpSocket 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
- \li \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).
-
- \li \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}.
-
- \li \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{Mandelbrot Example} and
- the \l{network/blockingfortuneclient}{Blocking Fortune Client}
- example.
-
- \section1 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 a thread other than the one
- that \e owns the object (or accessing the object in other ways) is
- unsafe, unless you guarantee that the object isn't processing
- events at that moment. Use QObject::deleteLater() instead, and a
- \l{QEvent::DeferredDelete}{DeferredDelete} event will be posted,
- which the event loop of the object's thread will eventually pick
- up. By default, the thread that \e owns a QObject is the thread
- that \e creates the QObject, but not after QObject::moveToThread()
- has been called.
-
- 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.
-
- \section1 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.
-
- \section1 Signals and Slots Across Threads
-
- Qt supports these signal-slot connection types:
-
- \list
-
- \li \l{Qt::AutoConnection}{Auto Connection} (default) If the signal is
- emitted in the thread which the receiving object has affinity then
- the behavior is the same as the Direct Connection. Otherwise,
- the behavior is the same as the Queued Connection."
-
- \li \l{Qt::DirectConnection}{Direct Connection} The slot is invoked
- immediately, when the signal is emitted. The slot is executed
- in the emitter's thread, which is not necessarily the
- receiver's thread.
-
- \li \l{Qt::QueuedConnection}{Queued Connection} The slot is invoked
- when control returns to the event loop of the receiver's
- thread. The slot is executed in the receiver's thread.
-
- \li \l{Qt::BlockingQueuedConnection}{Blocking Queued Connection}
- The slot is invoked as for the Queued Connection, except the
- current thread blocks until the slot returns. \note Using this
- type to connect objects in the same thread will cause deadlock.
-
- \li \l{Qt::UniqueConnection}{Unique Connection} The behavior is the
- same as the Auto Connection, but the connection is made only if
- it does not duplicate an existing connection. i.e., if the same
- signal is already connected to the same slot for the same pair
- of objects, then the connection is not made and connect()
- returns \c false.
-
- \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{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.
-*/
-
-/*!
- \page threads-modules.html
- \title Thread-Support in Qt Modules
-
- \previouspage Threads and QObjects
- \contentspage Thread Support in Qt
-
- \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 in a thread 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.
-
- \section1 Threads and Rich Text Processing
-
- The QTextDocument, QTextCursor, and \l{richtext.html}{all related classes} 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.
-
- \section1 Threads and Implicitly Shared Classes
-
- 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{Reentrancy and Thread-Safety}{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{Reentrancy and Thread-Safety}{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{Reentrancy and Thread-Safety}{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.
-*/
diff --git a/src/xml/doc/qtxml.qdocconf b/src/xml/doc/qtxml.qdocconf
index 19561af57f..7f8fddfd11 100644
--- a/src/xml/doc/qtxml.qdocconf
+++ b/src/xml/doc/qtxml.qdocconf
@@ -27,7 +27,7 @@ qhp.QtXml.subprojects.classes.sortPages = true
tagfile = ../../../doc/qtxml/qtxml.tags
-depends += qtcore qtnetwork
+depends += qtcore qtnetwork qtdoc
headerdirs += ..