[Qt learning] multi-threaded Qthread operations
I,QThread class overview
The QThread class provides a platform-independent way for users to manage multithreading.
# Include
Inherited from QObject class
II,QThread class details
The QThread object manages the control threads in the program. The QThread starts from the execution of the run () function. By default, run () starts the event loop by calling exec () and executes the Qt event loop within the thread.
The following example adds a worker object to a thread by calling QObject: moveToThread:
class Worker : public QObject { Q_OBJECT QThread workerThread; public slots: void doWork(const QString str) { // ... 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, SIGNAL(finished()), worker, SLOT(deleteLater())); connect(this, SIGNAL(operate(QString)), worker, SLOT(doWork(QString))); connect(worker, SIGNAL(resultReady(QString)), this, SLOT(handleResults(QString))); workerThread.start(); } ~Controller() { workerThread.quit(); workerThread.wait(); } public slots: void handleResults(const QString &); signals: void operate(const QString &); };
The code in the Worker slot will be run in an independent thread. You can connect the Worker slots to the signal of any object as needed. Benefiting from the queued connections mechanism (an event is distributed to the event loop in the thread where the receiver is located, and when the event is passed, the corresponding slot is activated ), it is safe to connect signals and slots between different objects.
Another way to implement multithreading is to inherit the QThread class and re-implement the run () function, for example:
class Thread : public QThread{ Q_OBJECTpublic: Thread(); void setMessage(const QString &message); void stop();protected: void run();private: QString messageStr; volatile bool stopped; QUdpSocket *udpSpcket;};class ThreadDialog : public QDialog{ Q_OBJECTpublic: ThreadDialog(QWidget *parent = 0);protected: void closeEvent(QCloseEvent *event);private slots: void startOrStopThreadA(); void startOrStopThreadB();private: Thread threadA; Thread threadB; QPushButton *threadAButton; QPushButton *threadBButton;};
Note:
1. When the run () function returns, the thread exits ). If the exec () function is not called, no running event loop exists in the thread ).
2. It is important that the QThread Object usually exists in the (lives in) Creation thread, rather than in the thread it manages. This means that the QThread slot is executed in the context of its existing thread (home thread), rather than in the context of the thread it manages. Based on this, implementing a new slot in the QThread subclass is prone to errors, so it is not recommended.
3. If other methods (technique) are used to interact with different objects, rather than the queue signal-slot mechanism, in a multi-threaded program, you must be cautious about possible problems.
4. the thread of the GUI object must exist in the main thread.
Iii. ManagementQThread
Managing threads
When the thread starts running (started (), finished (), and terminated (), QThread sends a notification through the signal (). In turn, you can also call isFinished () and isRunning () to query the thread status.
To stop a (stop) thread, you can call exit () or quit (). In extreme cases, you can call terminate () force terminate a thread in the execution state-this is dangerous and is not recommended. You can use the setTerminationEnabled () function to enable/disable the terminate () function.
After Qt 4.8, The deallocate object can be deleted after the thread ends by connecting the finished () signal to the QObject: deleteLater () slot.
You can use wait () to block the calling thread until the execution of other threads ends (you can also specify a timeout value ).
The static functions currentThreadId () and currentThread () return the identifiers of the current execution thread ),
Call setObjectName () before the thread starts. You can specify a name for the thread as a different identifier from other threads. If setObjectName () is not called, the Class Name of the thread object runtime type is used as the thread name. For example, in the following example, the thread name is RenderThread:
class RenderThread : public QThread{ Q_OBJECT public: RenderThread(QObject *parent = 0); ~RenderThread(); void render(double centerX, double centerY, double scaleFactor, QSize resultSize); signals: void renderedImage(const QImage &image, double scaleFactor); protected: void run(); private: uint rgbFromWaveLength(double wave); QMutex mutex; QWaitCondition condition; };
Note:: This rule is currently not applicable to the Windows flash-compiled release.
The QThread class provides static and platform-independent sleep functions: sleep (), msleep (), usleep (), and longitude are seconds, milliseconds, and microseconds.
Note: Generally, wait () and sleep () should be unnecessary (unnecessary), because Qt is based on event-driven architecture. When using wait (), consider QTimer for finished () and sleep.
Iv. QThread priority
Enum Qthread: Priority
Constant |
Value |
Description |
QThread: IdlePriority |
0 |
Scheduling is performed only when no other threads are running. |
QThread: LowestPriority |
1 |
Not frequently scheduled than LowPriority |
QThread: LowPriority |
2 |
Not frequently scheduled than NormalPriority |
QThread: NormalPriority |
3 |
Default operating system priority |
QThread: HighPriority |
4 |
More frequent than NormalPriority Scheduling |
QThread: HighestPriority |
5 |
More frequent than HighPriority Scheduling |
QThread: TimeCriticalPriority |
6 |
Schedule as frequently as possible |
QThread: InheritPriority |
7 |
Use the same priority as creating your own thread. This is the default attribute.
|