標籤:i++ 控制 執行 1.5 設計 exit 實驗 物件導向 多線程
1. QThread類
(1)QThread是一個跨平台的多線程解決方案
(2)QThread以簡潔易用的方式實現多線程編程
2. QThread中的關鍵成員函數
(1)virtual void run() :線程函數,用於定義線程功能(執行流)。
(2)void start():啟動函數,將線程入口地址設定為run函數。啟動線程,新線程開始執行run函數。
(3)int exec():進入事件迴圈,直至調用exit()。返回線程退出事件迴圈的返回碼。
(4)void terminate():強制結束線程(不推薦)。
【編程實驗】多線程編程初探
//main.cpp
#include <QCoreApplication>#include <QThread>#include <QtDebug>class MyThread : public QThread{protected: //線程函數 void run() { qDebug() << objectName() << " : " << "run() begin"; for(int i=0; i<5; i++) { qDebug() << objectName() << " : " << i; sleep(1); } qDebug() << objectName() << " : " << "run() end"; }};int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); qDebug() << "main() begin"; MyThread t1; t1.setObjectName("t1"); t1.start(); MyThread t2; t2.setObjectName("t2"); t2.start(); for(int i=0; i<100000; i++) { for(int j=0; j<10000; j++) { } } qDebug() << "main() end"; return a.exec();}
3. 線程對象和線程的生命週期
(1)線程對象的生命期
①線程對象指的是由QThread類定義的一個對象,是一個Qt對象。其生命週期與一般的Qt對象具有相同的特點。
②每個Qt對象都關聯唯一一個線程環境,對象有明確的線程屬性。當一個對象在某線程中,這就和該線程建立血緣關係,這種關係會一直保持到它死去或者被moveToThread到另一個線程中。
(2)線程的生命期
(3)線程對象和線程的關係
①QThread類的“線程對象”能夠開啟新的線程,但它本身所處的線程與新線程不是同一個線程。線程對象和線程是兩個不同的概念。
②線程對象的生命週期必須≥由該對象建立出來的線程的生命週期。線程對象先出生,線程後出生,線程先死亡,線程對象後死亡。(這個設計原則對於所有用物件導向封裝線程的平台都適用)
③不同線程間的對象之間不能發展成為父子關係,因為線程這種父子關係隨時可能因線程的終止而終止,具有不可預見性。這也告訴我們不要線上程對象的run()函數中建立新的局部對象,並將this指標傳遞給該新對象作為其parent。因為this指的是線程對象本身,與這個新的局部對象位於兩個不同的線程中。
4. 線程的終止
(1)暴力終止:調用terminate()。但特彆強調,在工程開發中該函數是禁止使用的!terminate會使得作業系統暴力終止線程,而不會才考慮資料完整性,資源釋放等問題。
(2)優雅終止線程的解決方案
①run()函數執行結束是優雅終止線程的唯一方式
②線上程類中增加標誌變數m_toStop(volatile bool)
③通過m_toStop的值判斷是否需要從run()函數返回。
【編程實驗】優雅的線程式控制制
//main.cpp
5. 小結
(1)QThread是一個跨平台的多線程解決方案
(2)QThread以簡潔易用的方式實現多線程編程。
(3)void run()函數用於實現線程執行體。
(4)void start()啟動線程並執行run()函數。
(5)工程中禁用void terminate()函數結束線程。
第73課 Qt中的多線程編程