1.多線程的理解
在操作系統中線程和進程划分。
操作系統可以同時執行多個任務,每個任務就是進程;進程可以同時執行多個任務,每個任務就是線程。
線程之間相互獨立,搶占式執行。對於單核CPU來說同一時刻只能有一個線程執行,一個進程執行。
但是由於CPU不斷在這些進程間輪換執行,速度相對人的反應很快,不容易察覺。
既然這樣,為什么要使用多線程呢?
a.對於多核cpu,多線程程序充分利用硬件優勢
b.對於單核cpu,由於線程上下文的切換會降低整體運行效率。但是為了防止執行耗時操作時界面假死,我們必須把耗時操作單獨放在線程中后台執行,防止阻塞主線程無法刷新窗口。
我們來看一下程序的阻塞和非阻塞
這里主要說對於線程之間的公共資源,同時只能由一個線程操作,在此期間其他線程訪問將會被掛起直到上一次訪問結束,同樣客戶端執行界面刷新的主線程也會掛起。
非阻塞指的是,一個線程的操作不會阻塞其他線程對事件的接受和處理。
同步和異步
這里說的執行一個操作必須等待執行完成,下面的邏輯才會繼續執行,是為同步執行代碼
對函數調用后,不會等待執行結果,繼續執行下面的代碼,是為異步執行。
2.線程使用
QT中多線程得兩種處理方法
使用線程在程序執行長時間操作得時候彈出進度條
使用線程可以把占據時間長得程序中任務放到后台去處理
其中一種是繼承QThread得run函數,另外一種是把一個繼承於QObject得類轉移到一個Thread里。
1.繼承QThread
QThread繼承類只有run函數是在新線程里跑的,其他函數在創建QThread線程中運行
新建一個線程類ExportThread:QThread ,把耗時操作放在其中run函數中
2.把一個繼承於QObject的類轉移到一個Thread里
創建一個繼承自QObject類得類對象object,使用object.moveToThread(QThread *);
3.線程類中得槽函數在哪個線程中執行得問題
對於方法1中,槽函數在創建線程類對象得線程(一般是主線程)中執行
對於方法2中,槽函數在次線程中執行,通過信號槽調用,直接調用則都在調用線程中執行,
所以要把耗時操作放在槽函數中,外面信號觸發,
具體需要參考,connect函數中表示連接方式得參數
如下:
同步調用:信號發出后,當前線程等待槽函數執行完畢才能執行剩余代碼。
異步調用:信號發出后,立即執行剩余邏輯,不關心槽函數什么時候執行。
AutoConnection 信號和槽同一線程時,直接聯,不同線程時,隊列聯
DirectConnection 直接聯,在主線程中執行,同步調用,不依賴QT事件循環
QueueConnection 隊列,次線程中執行,異步調用,槽函數所在對象得線程必須啟用QT事件循環
BlockingQueuedConnection 阻塞聯,同步調用, 槽函數在次線程中執行,用信號量實現阻塞,
槽函數所在對象得線程必須啟用QT事件循環,此連接只能用於發
出信號得線程和槽函數執行線程不同得情況。
要么在發射信號得線程中執行
要么在接受者依附得線程中執行
線程安全