QThread Class
The QThread class provides a platform-independent way to manage threads. More...
| Header: | #include <QThread> |
| qmake: | QT += core |
| Inherits: | QObject |
Public Types
| enum | Priority { IdlePriority, LowestPriority, LowPriority, NormalPriority, HighPriority, …, InheritPriority } |
Detailed Description
A QThread object manages one thread of control within the program. QThreads begin executing in run(). By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread.
You can use worker objects by moving them to the thread using QObject::moveToThread().
class Worker : public QObject { Q_OBJECT public slots: void doWork(const QString ¶meter) { QString result; /* ... here is the expensive or blocking operation ... */ emit resultReady(result); } signals: void resultReady(const QString &result); }; class Controller : public QObject { Q_OBJECT QThread workerThread; public: Controller() { Worker *worker = new Worker; worker->moveToThread(&workerThread); connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); connect(this, &Controller::operate, worker, &Worker::doWork); connect(worker, &Worker::resultReady, this, &Controller::handleResults); workerThread.start(); } ~Controller() { workerThread.quit(); workerThread.wait(); } public slots: void handleResults(const QString &); signals: void operate(const QString &); };
The code inside the Worker's slot would then execute in a separate thread. However, you are free to connect the Worker's slots to any signal, from any object, in any thread. It is safe to connect signals and slots across different threads, thanks to a mechanism called queued connections.
Another way to make code run in a separate thread, is to subclass QThread and reimplement run(). For example:
class WorkerThread : public QThread { Q_OBJECT void run() override { QString result; /* ... here is the expensive or blocking operation ... */ emit resultReady(result); } signals: void resultReady(const QString &s); }; void MyObject::startWorkInAThread() { WorkerThread *workerThread = new WorkerThread(this); connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults); connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater); workerThread->start(); }
In that example, the thread will exit after the run function has returned. There will not be any event loop running in the thread unless you call exec().
It is important to remember that a QThread instance lives in the old thread that instantiated it, not in the new thread that calls run(). This means that all of QThread's queued slots and invoked methods will execute in the old thread. Thus, a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassed QThread.
Unlike queued slots or invoked methods, methods called directly on the QThread object will execute in the thread that calls the method. When subclassing QThread, keep in mind that the constructor executes in the old thread while run() executes in the new thread. If a member variable is accessed from both functions, then the variable is accessed from two different threads. Check that it is safe to do so.
Note: Care must be taken when interacting with objects across different threads. As a general rule, functions can only be called from the thread that created the QThread object itself (e.g. setPriority()), unless the documentation says otherwise. See Synchronizing Threads for details.
Managing Threads
QThread will notify you via a signal when the thread is started() and finished(), or you can use isFinished() and isRunning() to query the state of the thread.
You can stop the thread by calling exit() or quit(). In extreme cases, you may want to forcibly terminate() an executing thread. However, doing so is dangerous and discouraged. Please read the documentation for terminate() and setTerminationEnabled() for detailed information.
From Qt 4.8 onwards, it is possible to deallocate objects that live in a thread that has just ended, by connecting the finished() signal to QObject::deleteLater().
Use wait() to block the calling thread, until the other thread has finished execution (or until a specified time has passed).
QThread also provides static, platform independent sleep functions: sleep(), msleep(), and usleep() allow full second, millisecond, and microsecond resolution respectively. These functions were made public in Qt 5.0.
Note: wait() and the sleep() functions should be unnecessary in general, since Qt is an event-driven framework. Instead of wait(), consider listening for the finished() signal. Instead of the sleep() functions, consider using QTimer.
The static functions currentThreadId() and currentThread() return identifiers for the currently executing thread. The former returns a platform specific ID for the thread; the latter returns a QThread pointer.
To choose the name that your thread will be given (as identified by the command ps -L on Linux, for example), you can call setObjectName() before starting the thread. If you don't call setObjectName(), the name given to your thread will be the class name of the runtime type of your thread object (for example, "RenderThread" in the case of the Mandelbrot Example, as that is the name of the QThread subclass). Note that this is currently not available with release builds on Windows.
See also Thread Support in Qt, QThreadStorage, Synchronizing Threads, Mandelbrot Example, Semaphores Example, and Wait Conditions Example.
Member Type Documentation
enum QThread::Priority
This enum type indicates how the operating system should schedule newly created threads.
| Constant | Value | Description |
|---|---|---|
QThread::IdlePriority | 0 | scheduled only when no other threads are running. |
QThread::LowestPriority | 1 | scheduled less often than LowPriority. |
QThread::LowPriority | 2 | scheduled less often than NormalPriority. |
QThread::NormalPriority | 3 | the default priority of the operating system. |
QThread::HighPriority | 4 | scheduled more often than NormalPriority. |
QThread::HighestPriority | 5 | scheduled more often than HighPriority. |
QThread::TimeCriticalPriority | 6 | scheduled as often as possible. |
QThread::InheritPriority | 7 | use the same priority as the creating thread. This is the default. |