summaryrefslogtreecommitdiffstats
path: root/src/corelib/doc
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/doc')
-rw-r--r--src/corelib/doc/images/thread_clock.pngbin5964 -> 0 bytes
-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/qtcore.qdocconf4
-rw-r--r--src/corelib/doc/snippets/code/doc_src_resources.cpp15
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp4
-rw-r--r--src/corelib/doc/snippets/qtracer/ftracer.cpp180
-rw-r--r--src/corelib/doc/snippets/qtracer/main.cpp59
-rw-r--r--src/corelib/doc/snippets/qtracer/qtracer.pro2
-rw-r--r--src/corelib/doc/src/custom-types.qdoc7
-rw-r--r--src/corelib/doc/src/objectmodel/object.qdoc3
-rw-r--r--src/corelib/doc/src/objectmodel/signalsandslots.qdoc2
-rw-r--r--src/corelib/doc/src/plugins-howto.qdoc5
-rw-r--r--src/corelib/doc/src/resource-system.qdoc34
-rw-r--r--src/corelib/doc/src/threads-basics.qdoc365
-rw-r--r--src/corelib/doc/src/threads.qdoc828
16 files changed, 54 insertions, 1454 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/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/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index fdd46995c5..9ab66c6645 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -2,7 +2,7 @@ include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
project = QtCore
description = Qt Core Reference Documentation
-url = http://qt-project.org/doc/qt-$QT_VER/qtcore
+url = http://qt-project.org/doc/qt-$QT_VER
version = $QT_VERSION
examplesinstallpath = core
@@ -26,7 +26,7 @@ qhp.QtCore.subprojects.classes.sortPages = true
tagfile = ../../../doc/qtcore/qtcore.tags
-depends += qtgui qtwidgets qtnetwork qtdoc qtquick qtlinguist qtdesigner
+depends += qtgui qtwidgets qtnetwork qtdoc qtquick qtlinguist qtdesigner qtconcurrent qtxml
headerdirs += ..
diff --git a/src/corelib/doc/snippets/code/doc_src_resources.cpp b/src/corelib/doc/snippets/code/doc_src_resources.cpp
index 482c25a222..8ac7b0e970 100644
--- a/src/corelib/doc/snippets/code/doc_src_resources.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_resources.cpp
@@ -44,11 +44,24 @@ QResource::registerResource("/path/to/myresource.rcc");
//! [5]
+MyClass::MyClass() : BaseClass()
+{
+ Q_INIT_RESOURCE(resources);
+
+ QFile file("qrc:/myfile.dat");
+ ...
+}
+//! [5]
+
+
+//! [6]
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Q_INIT_RESOURCE(graphlib);
+
+ QFile file("qrc:/graph.png");
...
return app.exec();
}
-//! [5]
+//! [6]
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
index 003fce580b..9210d2737f 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
@@ -416,7 +416,7 @@ text.data(); // returns "Qt is great!"
//! [46]
QString tmp = "test";
QByteArray text = tmp.toLocal8Bit();
-char *data = new char[text.size()]
+char *data = new char[text.size()];
strcpy(data, text.data());
delete [] data;
//! [46]
@@ -424,7 +424,7 @@ delete [] data;
//! [47]
QString tmp = "test";
QByteArray text = tmp.toLocal8Bit();
-char *data = new char[text.size() + 1]
+char *data = new char[text.size() + 1];
strcpy(data, text.data());
delete [] data;
//! [47]
diff --git a/src/corelib/doc/snippets/qtracer/ftracer.cpp b/src/corelib/doc/snippets/qtracer/ftracer.cpp
deleted file mode 100644
index b12e3ed9c3..0000000000
--- a/src/corelib/doc/snippets/qtracer/ftracer.cpp
+++ /dev/null
@@ -1,180 +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 examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <QCoreApplication>
-#include <QLoggingCategory>
-
-
-//![1]
-QLoggingCategory theFooArea("foo");
-QLoggingCategory theBarArea("bar");
-QLoggingCategory theBazArea("baz");
-//![1]
-
-// Note: These locations are Ubuntu specific.
-
-// Note: To make the example work with user permissions, make sure
-// the files are user-writable and the path leading there accessible.
-
-const char traceSwitch[] = "/sys/kernel/debug/tracing/tracing_on";
-const char traceSink[] = "/sys/kernel/debug/tracing/trace_marker";
-
-// The base class only serves as a facility to share code
-// between the "single line" data logging aspect and the
-// scoped "measuring" aspect.
-
-// Both aspects and the base class could be combined into
-// a single tracer serving both purposes, but are split
-// here for clarity.
-
-// Error handling is left as an exercise.
-
-//![2]
-class MyTracerBase : public QTracer
-{
-public:
- MyTracerBase() {
- enable = ::open(traceSwitch, O_WRONLY);
- marker = ::open(traceSink, O_WRONLY);
- }
-
- ~MyTracerBase() {
- ::close(enable);
- ::close(marker);
- }
-
-protected:
- int enable;
- int marker;
-};
-//![2]
-
-
-//![2]
-class MyTracer : public MyTracerBase
-{
-public:
- void start() { ::write(marker, "B", 1); }
- void end() { ::write(marker, "E", 1); }
-};
-//![2]
-
-
-//![3]
-class MyDataLogger : public MyTracerBase
-{
-public:
- MyDataLogger() {
- buf[0] = 0;
- pos = 0;
- }
-
- void record(int i) { pos += sprintf(buf + pos, "%d", i); }
- void record(const char *msg) { pos += sprintf(buf + pos, "%s", msg); }
- void end() { ::write(marker, buf, pos); pos = 0; }
-
-private:
- char buf[100];
- int pos;
-};
-//![3]
-
-// Simplest possible example for "measuring".
-//![4]
-int foo(int i)
-{
- qCTraceGuard(theFooArea);
- // Here could be some lengthy code.
- return i * i;
-}
-//![4]
-
-// We can switch on/off tracing dynamically.
-// The tracer will be temporarily switched off at the third call
-// and re-enabled at the eighth.
-//![5]
-int bar(int i)
-{
- static int n = 0;
- ++n;
- if (n == 3)
- theBarArea.setEnabled(QtTraceMsg, false);
- if (n == 8)
- theBarArea.setEnabled(QtTraceMsg, true);
-
- qCTraceGuard(theBarArea);
- return i * i;
-}
-//![5]
-
-// An example to create "complex" log messages.
-//![6]
-int baz(int i)
-{
- qCTrace(theBazArea) << 32 << "some stuff";
-
- return i * i;
-}
-//![6]
-
-
-
-//![7]
-namespace {
-static struct Init
-{
- Init() {
- tracer.addToCategory(theFooArea);
- tracer.addToCategory(theBarArea);
- logger.addToCategory(theBazArea);
- }
-
- MyTracer tracer;
- MyDataLogger logger;
-
-} initializer;
-}
-//![7]
diff --git a/src/corelib/doc/snippets/qtracer/main.cpp b/src/corelib/doc/snippets/qtracer/main.cpp
deleted file mode 100644
index 758a2bbdb8..0000000000
--- a/src/corelib/doc/snippets/qtracer/main.cpp
+++ /dev/null
@@ -1,59 +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 examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-int foo(int i);
-int bar(int i);
-int baz(int i);
-
-int main()
-{
- int s = 0;
- for (int i = 0; i != 10; ++i)
- s += foo(i);
-
- for (int i = 0; i != 10; ++i)
- s += bar(i);
-
- for (int i = 0; i != 10; ++i)
- s += baz(i);
-
- return s;
-}
-
diff --git a/src/corelib/doc/snippets/qtracer/qtracer.pro b/src/corelib/doc/snippets/qtracer/qtracer.pro
deleted file mode 100644
index 254e22be76..0000000000
--- a/src/corelib/doc/snippets/qtracer/qtracer.pro
+++ /dev/null
@@ -1,2 +0,0 @@
-
-SOURCES += ftracer.cpp main.cpp
diff --git a/src/corelib/doc/src/custom-types.qdoc b/src/corelib/doc/src/custom-types.qdoc
index cbf347a2f7..ed846aee83 100644
--- a/src/corelib/doc/src/custom-types.qdoc
+++ b/src/corelib/doc/src/custom-types.qdoc
@@ -155,10 +155,9 @@
The Q_DECLARE_METATYPE() macro and qRegisterMetaType() function documentation
contain more detailed information about their uses and limitations.
- The \l{Custom Type Example}{Custom Type},
- \l{Custom Type Sending Example}{Custom Type Sending}
- and \l{Queued Custom Type Example}{Queued Custom Type} examples show how to
- implement a custom type with the features outlined in this document.
+ The \l{Custom Type Example}{Custom Type} and \l{Queued Custom Type Example}
+ {Queued Custom Type} examples show how to implement a custom type with the
+ features outlined in this document.
The \l{Debugging Techniques} document provides an overview of the debugging
mechanisms discussed above.
diff --git a/src/corelib/doc/src/objectmodel/object.qdoc b/src/corelib/doc/src/objectmodel/object.qdoc
index 89a781da39..8d24096b7a 100644
--- a/src/corelib/doc/src/objectmodel/object.qdoc
+++ b/src/corelib/doc/src/objectmodel/object.qdoc
@@ -46,7 +46,8 @@
\li queryable and designable \l{Qt's Property System}{object
properties}
\li powerful \l{The Event System}{events and event filters}
- \li contextual \l{i18n}{string translation for internationalization}
+ \li contextual \l{Internationalization with Qt}{string translation for
+ internationalization}
\li sophisticated interval driven \l {Timers}{timers} that make it possible
to elegantly integrate many tasks in an event-driven GUI
\li hierarchical and queryable \l{Object Trees & Ownership}{object
diff --git a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
index dd93b80cae..e894d547d0 100644
--- a/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
+++ b/src/corelib/doc/src/objectmodel/signalsandslots.qdoc
@@ -275,7 +275,7 @@
and slot members, as well as pointers to these functions.
The meta-object contains additional information such as the
- object's \l{QObject::className()}{class name}. You can
+ object's \l{QMetaObject::className()}{class name}. You can
also check if an object \l{QObject::inherits()}{inherits}
a specific class, for example:
diff --git a/src/corelib/doc/src/plugins-howto.qdoc b/src/corelib/doc/src/plugins-howto.qdoc
index 2dbf1f8141..7565d610cc 100644
--- a/src/corelib/doc/src/plugins-howto.qdoc
+++ b/src/corelib/doc/src/plugins-howto.qdoc
@@ -35,10 +35,7 @@
These \l{Qt Core} classes deal with shared libraries, (e.g. .so and DLL
files), and with Qt plugins.
- See the \l{How to Create Qt Plugins} page for more information..
-
- See also the \l{ActiveQt framework} for Windows.
-
+ See the \l{How to Create Qt Plugins} page for more information.
*/
/*!
diff --git a/src/corelib/doc/src/resource-system.qdoc b/src/corelib/doc/src/resource-system.qdoc
index 5ef6bb285c..91ce8afcf8 100644
--- a/src/corelib/doc/src/resource-system.qdoc
+++ b/src/corelib/doc/src/resource-system.qdoc
@@ -184,15 +184,39 @@
path list is empty at startup; call QDir::addSearchPath() to
add paths to it.
- If you have resources in a static library, you might need to
- force initialization of your resources by calling \l
- Q_INIT_RESOURCE() with the base name of the \c .qrc file. For
- example:
+ \section1 Using Resources in a Library
+
+ If you have resources in a library, you need to force initialization
+ of your resources by calling \l Q_INIT_RESOURCE() with the base name
+ of the \c .qrc file. For example:
\snippet code/doc_src_resources.cpp 5
+ This ensures that the resources are linked into the final application
+ binary in the case of static linking. You should put the initialization
+ code close to where the resources are used in your library, so that
+ clients of your library will only link in the resources if they use
+ the feature of the library that depends on them.
+
+ Note: As the resource initializers generated by rcc are declared in the
+ global namespace, your calls to \l Q_INIT_RESOURCE() also need to be done
+ outside of any namespace.
+
+ If the library includes resources that are not used internally, but
+ instead exposed to clients of the library, the initialization needs
+ to happen in the application code. For example:
+
+ \snippet code/doc_src_resources.cpp 6
+
+ As before, this ensures that the resources are linked into the final
+ application binary in the case of static linking, but also triggers
+ loading of the library in the case of dynamic linking, such as plugins.
+
Similarly, if you must unload a set of resources explicitly
(because a plugin is being unloaded or the resources are not valid
any longer), you can force removal of your resources by calling
- Q_CLEANUP_RESOURCE() with the same base name as above.
+ \l Q_CLEANUP_RESOURCE() with the same base name as above.
+
+ Note: The use of \l Q_INIT_RESOURCE() and \l Q_CLEANUP_RESOURCE() is
+ not necessary when the resource is built as part of the application.
*/
diff --git a/src/corelib/doc/src/threads-basics.qdoc b/src/corelib/doc/src/threads-basics.qdoc
deleted file mode 100644
index 4f381421b4..0000000000
--- a/src/corelib/doc/src/threads-basics.qdoc
+++ /dev/null
@@ -1,365 +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
-
- 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.
-
- \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 890fd9f6ff..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 a 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 QReadWriteLocker, 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{threads/mandelbrot}{Mandelbrot} 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{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.
-*/
-
-/*!
- \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.
-*/