Doc: Discuss the concept of thread affinity in more detail

- Create a section dedicated to this concept, which is fundamental to
  signal/event handling
- Move relevant content from the very broad "Thread Basics" page to the
  QObject class ref
- Flesh out existing content, including distinguishing signals from
  events
- Address the common misconception that "member" = "child"; this has
  been encountered several times in the Qt Project forums

Change-Id: I5e7e6c848596e72c0bb623f8442c8389b81ad9ef
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
This commit is contained in:
Sze Howe Koh 2013-10-02 19:55:29 +08:00 committed by The Qt Project
parent 4e337ee703
commit 3b45dfe6e6
2 changed files with 37 additions and 31 deletions

View File

@ -185,19 +185,9 @@
\section2 QObject and Threads
A QObject is said to have a \e{thread affinity} or, in other words, that it
lives in a certain thread. This means that, at creation time, QObject saves
a pointer to the current thread. This information becomes relevant when an
event is posted with \l{QCoreApplication::}{postEvent()}. The event will be
put in the corresponding thread's event loop. If the thread where the
QObject lives doesn't have an event loop, the event will never be delivered.
To start an event loop, \l{QThread::}{exec()} must be called inside
\l{QThread::}{run()}. Thread affinity can be changed using
\l{QObject::}{moveToThread()}.
As mentioned above, developers must always be careful when calling objects'
methods from other threads. Thread affinity does not change this situation.
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.
@ -234,18 +224,6 @@
has terminated.
\endlist
A QObject's parent must always be in the same thread. This has a surprising
consequence for objects generated within the \l{QThread::}{run()} method:
\code
void HelloThread::run()
{
QObject *object1 = new QObject(this); //error, parent must be in the same thread
QObject object2; // OK
QSharedPointer <QObject> object3(new QObject); // OK
}
\endcode
\section2 Using a Mutex to Protect the Integrity of Data
A mutex is an object that has \l{QMutex::}{lock()} and \l{QMutex::}{unlock()}

View File

@ -522,13 +522,6 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
details. A convenience handler, childEvent(), can be reimplemented
to catch child events.
Events are delivered in the thread in which the object was
created; see \l{Thread Support in Qt} and thread() for details.
Note that event processing is not done at all for QObjects with no
thread affinity (thread() returns zero). Use the moveToThread()
function to change the thread affinity for an object and its
children (the object cannot be moved if it has a parent).
Last but not least, QObject provides the basic timer support in
Qt; see QTimer for high-level support for timers.
@ -549,6 +542,41 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
Some QObject functions, e.g. children(), return a QObjectList.
QObjectList is a typedef for QList<QObject *>.
\section1 Thread Affinity
A QObject instance is said to have a \e{thread affinity}, or that
it \e{lives} in a certain thread. When a QObject receives a
\l{Qt::QueuedConnection}{queued signal} or a \l{The Event
System#Sending Events}{posted event}, the slot or event handler
will run in the thread that the object lives in.
\note If a QObject has no thread affinity (that is, if thread()
returns zero), or if it lives in a thread that has no running event
loop, then it cannot receive queued signals or posted events.
By default, a QObject lives in the thread in which it is created.
An object's thread affinity can be queried using thread() and
changed using moveToThread().
All QObjects must live in the same thread as their parent. Consequently:
\list
\li setParent() will fail if the two QObjects involved live in
different threads.
\li When a QObject is moved to another thread, all its children
will be automatically moved too.
\li moveToThread() will fail if the QObject has a parent.
\li If \l{QObject}s are created within QThread::run(), they cannot
become children of the QThread object because the QThread does
not live in the thread that calls QThread::run().
\endlist
\note A QObject's member variables \e{do not} automatically become
its children. The parent-child relationship must be set by either
passing a pointer to the child's \l{QObject()}{constructor}, or by
calling setParent(). Without this step, the object's member variables
will remain in the old thread when moveToThread() is called.
\target No copy constructor
\section1 No copy constructor or assignment operator