| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** 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 The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/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: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \page thread-basics.html |
| \ingroup tutorials |
| \startpage {index.html}{Qt Reference Documentation} |
| |
| \title Threading Basics |
| \brief An introduction to threads |
| |
| \section1 What Are Threads? |
| |
| Threads are about doing things in parallel, just like processes. So how do |
| threads differ from processes? While you are making calculations on a |
| spreadsheet, there may also be a media player running on the same desktop |
| playing your favorite song. Here is an example of two processes working in |
| parallel: one running the spreadsheet program; one running a media player. |
| Multitasking is a well known term for this. A closer look at the media |
| player reveals that there are again things going on in parallel within one |
| single process. While the media player is sending music to the audio driver, |
| the user interface with all its bells and whistles is being constantly |
| updated. This is what threads are for -- concurrency within one single |
| process. |
| |
| So how is concurrency implemented? Parallel work on single core CPUs is an |
| illusion which is somewhat similar to the illusion of moving images in |
| cinema. |
| For processes, the illusion is produced by interrupting the processor's |
| work on one process after a very short time. Then the processor moves on to |
| the next process. In order to switch between processes, the current program |
| counter is saved and the next processor's program counter is loaded. This |
| is not sufficient because the same needs to be done with registers and |
| certain architecture and OS specific data. |
| |
| Just as one CPU can power two or more processes, it is also possible to let |
| the CPU run on two different code segments of one single process. When a |
| process starts, it always executes one code segment and therefore the |
| process is said to have one thread. However, the program may decide to |
| start a second thread. Then, two different code sequences are processed |
| simultaneously inside one process. Concurrency is achieved on single core |
| CPUs by repeatedly saving program counters and registers then loading the |
| next thread's program counters and registers. No cooperation from the |
| program is required to cycle between the active threads. A thread may be in |
| any state when the switch to the next thread occurs. |
| |
| The current trend in CPU design is to have several cores. A typical |
| single-threaded application can make use of only one core. However, a |
| program with multiple threads can be assigned to multiple cores, making |
| things happen in a truly concurrent way. As a result, distributing work |
| to more than one thread can make a program run much faster on multicore |
| CPUs because additional cores can be used. |
| |
| \section2 GUI Thread and Worker Thread |
| |
| As mentioned, each program has one thread when it is started. This thread |
| is called the "main thread" (also known as the "GUI thread" in Qt |
| applications). The Qt GUI must run in this thread. All widgets and several |
| related classes, for example QPixmap, don't work in secondary threads. |
| A secondary thread is commonly referred to as a "worker thread" because it |
| is used to offload processing work from the main thread. |
| |
| \section2 Simultaneous Access to Data |
| |
| Each thread has its own stack, which means each thread has its own call |
| history and local variables. Unlike processes, threads share the same |
| address space. The following diagram shows how the building blocks of |
| threads are located in memory. Program counter and registers of inactive |
| threads are typically kept in kernel space. There is a shared copy of the |
| code and a separate stack for each thread. |
| |
| \image threadvisual-example.png "Thread visualization" |
| |
| If two threads have a pointer to the same object, it is possible that both |
| threads will access that object at the same time and this can potentially |
| destroy the object's integrity. It's easy to imagine the many things that |
| can go wrong when two methods of the same object are executed |
| simultaneously. |
| |
| Sometimes it is necessary to access one object from different threads; |
| for example, when objects living in different threads need to communicate. |
| Since threads use the same address space, it is easier and faster for |
| threads to exchange data than it is for processes. Data does not have to be |
| serialized and copied. Passing pointers is possible, but there must be a |
| strict coordination of what thread touches which object. Simultaneous |
| execution of operations on one object must be prevented. There are several |
| ways of achieving this and some of them are described below. |
| |
| So what can be done safely? All objects created in a thread can be used |
| safely within that thread provided that other threads don't have references |
| to them and objects don't have implicit coupling with other threads. Such |
| implicit coupling may happen when data is shared between instances as with |
| static members, singletons or global data. Familiarize yourself with the |
| concept of \l{Reentrancy and Thread-Safety}{thread safe and reentrant} |
| classes and functions. |
| |
| \section1 Using Threads |
| |
| There are basically two use cases for threads: |
| |
| \list |
| \li Make processing faster by making use of multicore processors. |
| \li Keep the GUI thread or other time critical threads responsive by |
| offloading long lasting processing or blocking calls to other threads. |
| \endlist |
| |
| \section2 When to Use Alternatives to Threads |
| |
| Developers need to be very careful with threads. It is easy to start other |
| threads, but very hard to ensure that all shared data remains consistent. |
| Problems are often hard to find because they may only show up once in a |
| while or only on specific hardware configurations. Before creating threads |
| to solve certain problems, possible alternatives should be considered. |
| |
| \table |
| \header |
| \li Alternative |
| \li Comment |
| \row |
| \li QEventLoop::processEvents() |
| \li Calling QEventLoop::processEvents() repeatedly during a |
| time-consuming calculation prevents GUI blocking. However, this |
| solution doesn't scale well because the call to processEvents() may |
| occur too often, or not often enough, depending on hardware. |
| \row |
| \li QTimer |
| \li Background processing can sometimes be done conveniently using a |
| timer to schedule execution of a slot at some point in the future. |
| A timer with an interval of 0 will time out as soon as there are no |
| more events to process. |
| \row |
| \li QSocketNotifier QNetworkAccessManager QIODevice::readyRead() |
| \li This is an alternative to having one or multiple threads, each with |
| a blocking read on a slow network connection. As long as the |
| calculation in response to a chunk of network data can be executed |
| quickly, this reactive design is better than synchronous waiting in |
| threads. Reactive design is less error prone and energy efficient |
| than threading. In many cases there are also performance benefits. |
| \endtable |
| |
| In general, it is recommended to only use safe and tested paths and to |
| avoid introducing ad-hoc threading concepts. The QtConcurrent module provides an easy |
| interface for distributing work to all of the processor's cores. The |
| threading code is completely hidden in the QtConcurrent framework, so you |
| don't have to take care of the details. However, QtConcurrent can't be used |
| when communication with the running thread is needed, and it shouldn't be |
| used to handle blocking operations. |
| |
| \section2 Which Qt Thread Technology Should You Use? |
| |
| See the \l{Multithreading Technologies in Qt} page for an introduction to the |
| different approaches to multithreading to Qt, and for guidelines on how to |
| choose among them. |
| |
| |
| \section1 Qt Thread Basics |
| |
| The following sections describe how QObjects interact with threads, how |
| programs can safely access data from multiple threads, and how asynchronous |
| execution produces results without blocking a thread. |
| |
| \section2 QObject and Threads |
| |
| As mentioned above, developers must always be careful when calling objects' |
| methods from other threads. \l{QObject#Thread Affinity}{Thread affinity} |
| does not change this situation. |
| Qt documentation marks several methods as thread-safe. |
| \l{QCoreApplication::}{postEvent()} is a noteworthy example. A thread-safe |
| method may be called from different threads simultaneously. |
| |
| In cases where there is usually no concurrent access to methods, calling |
| non-thread-safe methods of objects in other threads may work thousands |
| of times before a concurrent access occurs, causing unexpected behavior. |
| Writing test code does not entirely ensure thread correctness, but it is |
| still important. |
| On Linux, Valgrind and Helgrind can help detect threading errors. |
| |
| \section2 Protecting the Integrity of Data |
| |
| When writing a multithread application, extra care must be taken to avoid |
| data corruption. See \l{Synchronizing Threads} for a discussion on how to |
| use threads safely. |
| |
| \section2 Dealing with Asynchronous Execution |
| |
| One way to obtain a worker thread's result is by waiting for the thread |
| to terminate. In many cases, however, a blocking wait isn't acceptable. The |
| alternative to a blocking wait are asynchronous result deliveries with |
| either posted events or queued signals and slots. This generates a certain |
| overhead because an operation's result does not appear on the next source |
| line, but in a slot located somewhere else in the source file. Qt |
| developers are used to working with this kind of asynchronous behavior |
| because it is much similar to the kind of event-driven programming used in |
| GUI applications. |
| |
| \section1 Examples |
| |
| Qt comes with several examples for using threads. See the class references |
| for QThread and QThreadPool for simple examples. See the \l{Threading and |
| Concurrent Programming Examples} page for more advanced ones. |
| |
| \section1 Digging Deeper |
| |
| Threading is a very complicated subject. Qt offers more classes for |
| threading than we have presented in this tutorial. The following materials |
| can help you go into the subject in more depth: |
| |
| \list |
| \li 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 |
| */ |