Sophie

Sophie

distrib > Mandriva > 2010.0 > i586 > media > contrib-release > by-pkgid > a6711891ce757817bba854bf3f25205a > files > 2544

qtjambi-doc-4.3.3-3mdv2008.1.i586.rpm

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- /home/gvatteka/dev/qt-4.3/doc/src/threads.qdoc -->
<head>
  <title>Thread Support in Qt</title>
  <link href="classic.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1 align="center">Thread Support in Qt<br /><small></small></h1>
<p>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.</p>
<p>Earlier versions of Qt offered an option to build the library without thread support. Since Qt 4.0, threads are always enabled.</p>
<p>This document is intended for an audience that has knowledge of, and experience with, multithreaded applications. If you are new to threading see our <a href="threads.html#reading">Recommended Reading</tt></a> list.</p>
<p>Topics:</p>
<ul><li><a href="#the-threading-classes">The Threading Classes</a></li>
<ul><li><a href="#creating-a-thread">Creating a Thread</a></li>
<li><a href="#synchronizing-threads">Synchronizing Threads</a></li>
</ul>
<li><a href="#reentrancy-and-thread-safety">Reentrancy and Thread-Safety</a></li>
<li><a href="#threads-and-qobjects">Threads and QObjects</a></li>
<ul><li><a href="#qobject-reentrancy">QObject Reentrancy</a></li>
<li><a href="#per-thread-event-loop">Per-Thread Event Loop</a></li>
<li><a href="#accessing-qobject-subclasses-from-other-threads">Accessing QObject Subclasses from Other Threads</a></li>
<li><a href="#signals-and-slots-across-threads">Signals and Slots Across Threads</a></li>
</ul>
<li><a href="#threads-and-implicit-sharing">Threads and Implicit Sharing</a></li>
<li><a href="#threads-and-the-sql-module">Threads and the SQL Module</a></li>
<li><a href="#recommended-reading">Recommended Reading</a></li>
</ul>
<a name="the-threading-classes"></a>
<h3>The Threading Classes</h3>
<p>Qt includes the following thread classes:</p>
<ul>
<li>QThread provides the means to start a new thread.</li>
<li>QThreadStorage provides per-thread data storage.</li>
<li><a href="core/QMutex.html"><tt>QMutex</tt></a> provides a mutual exclusion lock, or mutex.</li>
<li>QMutexLocker is a convenience class that automatically locks and unlocks a <a href="core/QMutex.html"><tt>QMutex</tt></a>.</li>
<li><a href="gui/QReadWriteLock.html"><tt>QReadWriteLock</tt></a> provides a lock that allows simultaneous read access.</li>
<li>QReadLocker and QWriteLocker are convenience classes that automatically lock and unlock a <a href="gui/QReadWriteLock.html"><tt>QReadWriteLock</tt></a>.</li>
<li><a href="core/QSemaphore.html"><tt>QSemaphore</tt></a> provides an integer semaphore (a generalization of a mutex).</li>
<li><a href="core/QWaitCondition.html"><tt>QWaitCondition</tt></a> provides a way for threads to go to sleep until woken up by another thread.</li>
</ul>
<p><b>Note:</b> Qt's threading classes are implemented with native threading APIs; e.g&#x2e;, Win32 and pthreads. Therefore, they can be used with threads of the same native API.</p>
<a name="creating-a-thread"></a>
<h4>Creating a Thread</h4>
<p>To create a thread, subclass QThread and reimplement its run() function. For example:</p>
<pre>    class MyThread : public QThread
    {
        Q_OBJECT

    protected:
        void run();
    };

    void MyThread::run()
    {
        ...
    }</pre>
<p>Then, create an instance of the thread object and call QThread::start(). The code that appears in the run() reimplementation will then be executed in a separate thread. Creating threads is explained in more detail in the QThread documentation.</p>
<p>Note that QCoreApplication::exec() must always be called from the main thread (the thread that executes <tt>main()</tt>), not from a QThread. In GUI applications, the main thread is also called the GUI thread because it's the only thread that is allowed to perform GUI-related operations.</p>
<p>In addition, you must create the <a href="gui/QApplication.html"><tt>QApplication</tt></a> (or <a href="core/QCoreApplication.html"><tt>QCoreApplication</tt></a>) object before you can create a QThread.</p>
<a name="synchronizing-threads"></a>
<h4>Synchronizing Threads</h4>
<p>The <a href="core/QMutex.html"><tt>QMutex</tt></a>, <a href="gui/QReadWriteLock.html"><tt>QReadWriteLock</tt></a>, <a href="core/QSemaphore.html"><tt>QSemaphore</tt></a>, and <a href="core/QWaitCondition.html"><tt>QWaitCondition</tt></a> classes provide means to synchronize threads. While the main idea with threads is that they should be as concurrent as possible, there are points where threads must stop and wait for other threads. For example, if two threads try to access the same global variable simultaneously, the results are usually undefined.</p>
<p><a href="core/QMutex.html"><tt>QMutex</tt></a> provides a mutually exclusive lock, or mutex. At most one thread can hold the mutex at any time. If a thread tries to acquire the mutex while the mutex is already locked, the thread will be put to sleep until the thread that currently holds the mutex unlocks it. Mutexes are often used to protect accesses to shared data (i.e&#x2e;, data that can be accessed from multiple threads simultaneously). In the <a href="threads.html#reentrancy-and-thread-safety">Reentrancy and Thread-Safety</tt></a> section below, we will use it to make a class thread-safe.</p>
<p><a href="gui/QReadWriteLock.html"><tt>QReadWriteLock</tt></a> is similar to <a href="core/QMutex.html"><tt>QMutex</tt></a>, except that it distinguishes between &quot;read&quot; and &quot;write&quot; access to shared data and allows multiple readers to access the data simultaneously. Using <a href="gui/QReadWriteLock.html"><tt>QReadWriteLock</tt></a> instead of <a href="core/QMutex.html"><tt>QMutex</tt></a> when it is possible can make multithreaded programs more concurrent.</p>
<p><a href="core/QSemaphore.html"><tt>QSemaphore</tt></a> is a generalization of <a href="core/QMutex.html"><tt>QMutex</tt></a> that protects a certain number of identical resources. In contrast, a mutex protects exactly one resource. The Semaphores</tt> example shows a typical application of semaphores: synchronizing access to a circular buffer between a producer and a consumer.</p>
<p><a href="core/QWaitCondition.html"><tt>QWaitCondition</tt></a> allows a thread to wake up other threads when some condition has been met. One or many threads can block waiting for a <a href="core/QWaitCondition.html"><tt>QWaitCondition</tt></a> to set a condition with wakeOne() or wakeAll(). Use wakeOne() to wake one randomly selected event or wakeAll() to wake them all. The Wait Conditions</tt> example shows how to solve the producer-consumer problem using <a href="core/QWaitCondition.html"><tt>QWaitCondition</tt></a> instead of <a href="core/QSemaphore.html"><tt>QSemaphore</tt></a>.</p>
<p>Note that Qt's synchronization classes rely on the use of properly aligned pointers. For instance, you cannot use packed classes with MSVC.</p>
<a name="reentrant"></a><a name="thread-safe"></a><a name="reentrancy-and-thread-safety"></a>
<h3>Reentrancy and Thread-Safety</h3>
<p>Throughout the Qt documentation, the terms <i>reentrant</i> and <i>thread-safe</i> are used to specify how a function can be used in multithreaded applications:</p>
<ul>
<li>A <i>reentrant</i> function can be called simultaneously by multiple threads provided that each invocation of the function references unique data.</li>
<li>A <i>thread-safe</i> function can be called simultaneously by multiple threads when each invocation references shared data. All access to the shared data is serialized.</li>
</ul>
<p>By extension, a class is said to be reentrant if each and every one of its functions can be called simultaneously by multiple threads on different instances of the class. Similarly, the class is said to be thread-safe if the functions can be called by different threads on the same instance.</p>
<p>Classes in the documentation will be documented as thread-safe only if they are intended to be used by multiple threads.</p>
<p>Note that the terminology in this domain isn't entirely standardized. POSIX uses a somewhat different definition of reentrancy and thread-safety for its C APIs. When dealing with an object-oriented C++ class library such as Qt, the definitions must be adapted.</p>
<p>Most C++ classes are inherently reentrant, since they typically only reference member data. Any thread can call such a member function on an instance of the class, as long as no other thread is calling a member function on the same instance. For example, the <tt>Counter</tt> class below is reentrant:</p>
<pre>    class Counter
    {
    public:
        Counter() { n = 0; }

        void increment() { ++n; }
        void decrement() { --n; }
        int value() const { return n; }

    private:
        int n;
    };</pre>
<p>The class isn't thread-safe, because if multiple threads try to modify the data member <tt>n</tt>, the result is undefined. This is because C++'s <tt>++</tt> and <tt>--</tt> operators aren't necessarily atomic. Indeed, they usually expand to three machine instructions:</p>
<ol type="1">
<li>Load the variable's value in a register.</li>
<li>Increment or decrement the register's value.</li>
<li>Store the register's value back into main memory.</li>
</ol>
<p>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!</p>
<p>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 <a href="core/QMutex.html"><tt>QMutex</tt></a>:</p>
<pre>    class Counter
    {
    public:
        Counter() { n = 0; }

        void increment() { QMutexLocker locker(&amp;mutex); ++n; }
        void decrement() { QMutexLocker locker(&amp;mutex); --n; }
        int value() const { QMutexLocker locker(&amp;mutex); return n; }

    private:
        mutable QMutex mutex;
        int n;
    };</pre>
<p>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 <tt>mutex</tt> data member is declared with the <tt>mutable</tt> qualifier because we need to lock and unlock the mutex in <tt>value()</tt>, which is a const function.</p>
<p>Most Qt classes are reentrant and not thread-safe, to avoid the overhead of repeatedly locking and unlocking a <a href="core/QMutex.html"><tt>QMutex</tt></a>. For example, <a href="porting4.html#qstring"><tt>QString</tt></a> is reentrant, meaning that you can use it in different threads, but you can't access the same <a href="porting4.html#qstring"><tt>QString</tt></a> object from different threads simultaneously (unless you protect it with a mutex yourself). A few classes and functions are thread-safe; these are mainly thread-related classes such as <a href="core/QMutex.html"><tt>QMutex</tt></a>, or fundamental functions such as QCoreApplication::postEvent().</p>
<a name="threads-and-qobjects"></a>
<h3>Threads and QObjects</h3>
<p>QThread inherits <a href="core/QObject.html"><tt>QObject</tt></a>. It emits signals to indicate that the thread started or finished executing, and provides a few slots as well.</p>
<p>More interesting is that <a href="core/QObject.html"><tt>QObject</tt></a>s can be used in multiple threads, emit signals that invoke slots in other threads, and post events to objects that &quot;live&quot; in other threads. This is possible because each thread is allowed to have its own event loop.</p>
<a name="qobject-reentrancy"></a>
<h4>QObject Reentrancy</h4>
<p><a href="core/QObject.html"><tt>QObject</tt></a> is reentrant. Most of its non-GUI subclasses, such as <a href="core/QTimer.html"><tt>QTimer</tt></a>, <a href="network/QTcpSocket.html"><tt>QTcpSocket</tt></a>, <a href="network/QUdpSocket.html"><tt>QUdpSocket</tt></a>, <a href="network/QHttp.html"><tt>QHttp</tt></a>, <a href="network/QFtp.html"><tt>QFtp</tt></a>, and <a href="core/QProcess.html"><tt>QProcess</tt></a>, 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:</p>
<ul>
<li><i>The child of a <a href="core/QObject.html"><tt>QObject</tt></a> must always be created in the thread where the parent was created.</i> This implies, among other things, that you should never pass the QThread object (<tt>this</tt>) as the parent of an object created in the thread (since the QThread object itself was created in another thread).</li>
<li><i>Event driven objects may only be used in a single thread.</i> Specifically, this applies to the <a href="timers.html">timer mechanism</tt></a> and the network module</tt>. For example, you cannot start a timer or connect a socket in a thread that is not the object's thread</tt>.</li>
<li><i>You must ensure that all objects created in a thread are deleted before you delete the QThread.</i> This can be done easily by creating the objects on the stack in your run() implementation.</li>
</ul>
<p>Although <a href="core/QObject.html"><tt>QObject</tt></a> is reentrant, the GUI classes, notably <a href="gui/QWidget.html"><tt>QWidget</tt></a> 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.</p>
<p>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 Mandelbrot</tt> and the Blocking Fortune Client</tt> example.</p>
<a name="per-thread-event-loop"></a>
<h4>Per-Thread Event Loop</h4>
<p>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 <a href="core/QCoreApplication.html"><tt>QCoreApplication</tt></a>, QThread provides an exit(int)</tt> function and a quit() slot.</p>
<p>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 <a href="core/QTimer.html"><tt>QTimer</tt></a>, <a href="network/QTcpSocket.html"><tt>QTcpSocket</tt></a>, and <a href="core/QProcess.html"><tt>QProcess</tt></a>). 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 <a href="threads.html#signals-and-slots-across-threads">Signals and Slots Across Threads</tt></a> section below.</p>
<p align="center"><img src="images/threadsandobjects.png" alt="Threads, objects, and event loops" /></p><p>A <a href="core/QObject.html"><tt>QObject</tt></a> instance is said to <i>live</i> 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 <a href="core/QObject.html"><tt>QObject</tt></a> lives is available using QObject::thread().</p>
<p>Note that for QObjects that are created before <a href="gui/QApplication.html"><tt>QApplication</tt></a>, 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).</p>
<p>Calling <tt>delete</tt> on a <a href="core/QObject.html"><tt>QObject</tt></a> from another thread than the thread where it is created (or accessing the object in other ways) is unsafe unless you can guarantee that the object isn't processing events at the same moment. Use QObject::deleteLater() instead; it will post a DeferredDelete event, which the event loop of the object's thread will eventually pick up.</p>
<p>If no event loop is running, events won't be delivered to the object. For example, if you create a <a href="core/QTimer.html"><tt>QTimer</tt></a> object in a thread but never call exec(), the <a href="core/QTimer.html"><tt>QTimer</tt></a> will never emit its timeout() signal. Calling deleteLater() won't work either. (These restrictions apply to the main thread as well.)</p>
<p>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.</p>
<p>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 postEvent()) can only be used to dispatch events to objects living in the thread from which the function is called.</p>
<a name="accessing-qobject-subclasses-from-other-threads"></a>
<h4>Accessing QObject Subclasses from Other Threads</h4>
<p><a href="core/QObject.html"><tt>QObject</tt></a> 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 <a href="core/QObject.html"><tt>QObject</tt></a> subclass while you are accessing the object from another thread.</p>
<p>If you are calling a function on an <a href="core/QObject.html"><tt>QObject</tt></a> subclass that doesn't live in the current thread and the object might receive events, you must protect all access to your <a href="core/QObject.html"><tt>QObject</tt></a> subclass's internal data with a mutex; otherwise, you may experience crashes or other undesired behavior.</p>
<p>Like other objects, QThread objects live in the thread where the object was created -- <i>not</i> 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.</p>
<p>On the other hand, you can safely emit signals from your QThread::run() implementation, because signal emission is thread-safe.</p>
<a name="signals-and-slots-across-threads"></a>
<h4>Signals and Slots Across Threads</h4>
<p>Qt supports three types of signal-slot connections:</p>
<ul>
<li>With direct connections</tt>, the slot gets called immediately when the signal is emitted. The slot is executed in the thread that emitted the signal (which is not necessarily the thread where the receiver object lives).</li>
<li>With queued connections</tt>, the slot is invoked when control returns to the event loop of the thread to which the object belongs. The slot is executed in the thread where the receiver object lives.</li>
<li>With auto connections</tt> (the default), the behavior is the same as with direct connections if the signal is emitted in the thread where the receiver lives; otherwise, the behavior is that of a queued connection.</li>
</ul>
<p>The connection type can be specified by passing an additional argument to 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.</p>
<p>QObject::connect() itself is thread-safe.</p>
<p>The Mandelbrot</tt> 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.</p>
<p>Similarly, the Blocking Fortune Client</tt> example uses a separate thread for communicating with a TCP server asynchronously.</p>
<a name="threads-and-implicit-sharing"></a>
<h3>Threads and Implicit Sharing</h3>
<p>Qt uses an optimization called implicit sharing</tt> for many of its value class, notably <a href="gui/QImage.html"><tt>QImage</tt></a> and <a href="porting4.html#qstring"><tt>QString</tt></a>. In many people's minds, implicit sharing and multithreading are incompatible concepts, because of the way the reference counting is typically done. One solution is to protect the internal reference counter with a mutex, but this is prohibitively slow. Earlier versions of Qt didn't provide a satisfactory solution to this problem.</p>
<p>Beginning with Qt 4, implicit shared classes can safely be copied across threads, like any other value classes. They are fully <a href="threads.html#reentrant">reentrant</tt></a>. The implicit sharing is really implicit. This is implemented using atomic reference counting operations, which are implemented in assembly language for the different platforms supported by Qt. Atomic reference counting is very fast, much faster than using a mutex (see also <a href="atomic-operations.html">Implementing Atomic Operations</tt></a>).</p>
<p>This having been said, if you access the same <i>object</i> in multiple threads simultaneously (as opposed to copies of the same object), you still need a mutex to serialize the accesses, just like with any reentrant class.</p>
<p>To sum it up, implicitly shared classes in Qt 4 are really <i>implicitly</i> shared. Even in multithreaded applications, you can safely use them as if they were plain, non-shared, reentrant classes.</p>
<a name="threads-and-the-sql-module"></a>
<h3>Threads and the SQL Module</h3>
<p>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.</p>
<p>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</p>
<a name="reading"></a><a name="recommended-reading"></a>
<h3>Recommended Reading</h3>
<ul>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/0134436989/trolltech/t">Threads Primer: A Guide to Multithreaded Programming</tt></a></li>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/0131900676/trolltech/t">Thread Time: The Multithreaded Programming Guide</tt></a></li>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/1565921151/trolltech/t">Pthreads Programming: A POSIX Standard for Better Multiprocessing</tt></a></li>
<li><a href="http://www.amazon.com/exec/obidos/ASIN/1565922964/trolltech/t"><tt>Win32 Multithreaded Programming</tt></a></li>
</ul>
<p /><address><hr /><div align="center">
<table width="100%" cellspacing="0" border="0"><tr class="address">
<td width="30%">Copyright &copy; 2007 <a href="trolltech.html">Trolltech</a></td>
<td width="40%" align="center"><a href="trademarks.html">Trademarks</a></td>
<td width="30%" align="right"><div align="right">Qt Jambi </div></td>
</tr></table></div></address></body>
</html>