您好,登錄后才能下訂單哦!
一、Qt中通過QThread直接支持多線程
1、QThread是一個跨平臺的多線程解決方案
2、QThread以簡潔易用的方式實現多線程編程
注意:1、Qt中的線程以對象的形式被創建和使用
2、每一個線程對應著一個QThread對象
QThread這個類,是一個線程父類,我們需要繼承這個QThread類。
QThread類,提供了一組成員函數。一個線程是以一個對象的形式來表現出來,所以說,我們創建一個
線程的時候,實際上就是創建了一個這個QThread線程類的對象
一個線程對應一個QThread對象
二、QThread中的關鍵成員函數
1、void run()
線程體函數,用于定義線程功能(執行流),是線程的入口函數。
2、void start()
啟動函數,在操作系統中真正創建出一個線程后,將線程入口地址設置為run函數
3、void terminate()
強制結束線程(不推薦)
三、自定義一個線程類
class MyThread : public QThread { protected: //保護,被保護的成員函數,不能直接被外界訪問,但是可以被子類直接訪問 void run() //重寫QThread類中的run成員函數,來實現我們線程體邏輯 { for ( int i = 0; i < 5; i++) { qDebug() << objectName() <<i; //objectName,當前對象的名字 sleep(1); //這個sleep函數,是QThread類里面的一個靜態的成員函數 } } }; int main(int argc, char *argv[]) { MyThread t; //創建子線程 t.setobjectName("t"); //設置t對象的名字為t t.start(); //啟動子線程 MyThread tt; //又創建了一個線程 tt.setobjectName("tt"); tt.start(); }
可以說是三個線程上面的,因為還包含了主線程,三個線程是并行執行的。宏觀上。
注意:上面代碼,主線程將先于子線程結束,所有子線程全部結束后,進程結束。
一個進程的結束,要等待內部的所有線程都結束后,才會結束。
四、線程的生命周期
1、用線程類創建一個對象時,可以說我們已經創建一個線程了,被創建的線程對象
調用start成員函數后,線程開始運行,運行的是run成員函數體,該線程參與操作
系統的調度,操作系統給每一個線程一定的時間片時間去執行,時間片到了當前線程
停止運行,其他線程運行它的時間片,如此調度,所以從單核cpu的角度看,微觀看,線程
是順序執行,由操作系統切換每個線程的執行。線程的非正常死亡之一是因terminate()
成員函數導致,所以terminate成員函數不推薦使用,因為不會考慮數據的完整性,
會暴力的殺死線程,可能會導致資源沒有被釋放,數據不完整等,所以在工程中
禁止調用。
2、不調用terminate()成員函數去結束一個線程,那如何優雅的結束一個線程的生命期呢?
(1)解決方案思路:
run()函數執行結束是優雅終止線程的唯一方式,因為是線程的自然死亡,run成員函數被執行完了
run成員函數被正常的返回了,這種叫做正常的死亡,所以在線程類中增加一個標志變量m_toStop(volatile bool),通過m_toStop的值判斷是否需要從run()函數返回。run函數返回,為優雅
的結束線程 。volatile關鍵字必須去修飾這個標志變量,不需要編譯去優化,而是我們每次都會去內存中去取這個值,值是易變的,所以加volatile。
3、代碼如下
class MyThread :public QThread { protected: volatile bool m_toStop; void run(); public: MyThread() { m_toStop = false; } void stop() { m_toStop = true; } }; void MyThread::run() { while (!m_toStop) { } }
上面的代碼,如果run函數中的while循環中,判斷到了m_toStop變量值為true了,
則會不執行while循環,跳出while循環,向下執行后,run函數就會自己返回,這個
方法是工程中,結束一個線程執行的一個很好的方法,標準優雅的去結束一個線程。
class MyThread :public QThread { protected: volatile bool m_toStop; void run() { int *p = new int[10000]; //申請了10000*int大小的堆空間讓p指向 for ( int i = 0; !m_toStop && (i < 10); i++ ) { p[i] = i * i; sleep(1); } delete[] p; } public: MyThread() { m_toStop = false; } void stop() { m_toStop = true; } };
int main(void)
{
MyThread t;
t.start();
Sleep(5000);
t.stop(); //優雅的結束線程
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。