保持Qt程序中GUI的響應流暢

如何使Qt 平臺中的GUI保持響應流暢?通常來講耗時較長的操做,分爲計算密集型操做和IO密集型操做,對於這兩類操做如何提升響應速度。網絡

而從操做的本質上來講,操做又可分爲不可分解操做,如在第三方庫中耗時較長的操做,以及可分解操做,其中可分解操做又可細分爲串行操做和可並行操做,如何針對這幾類操做來提升響應速度呢?多線程

如何將異步的操做,如網絡庫中異步的讀取數據方法,變成同步的操做?異步

此外對於多線程,廣泛的見解是能夠提供程序的運行速度,其實否則,不正確地使用線程經常會使程序變慢,那麼在QT中是否能夠經過多線程之外的方法來提升響應速度呢?本文給你解決。this

首先什麼是對GUI的響應?答:GUI的響應就是系統對於GUI事件的處理速度。操作系統

因爲系統處理事件須要必定的時間,因此通常窗口系統都會提供一個事件隊列來存儲事件。若是把每一個事件處理當作一個任務的話,那麼事件處理就相似於操做系統對於任務按照優先級進行處理,使得每一個任務的平均等待時間最小。那麼就能夠借鑑一下操做系統中的方法,好比:線程

分級,讓較長的任務延後執行。code

分時,對於較長的任務,讓其執行一段時間後暫停,而後再執行。隊列

減小每一個任務運行的耗時,固然這是最基本的方法。事件

先看第一個分級,當一個事件處理程序知道本身將執行耗時很長的操做時,能夠調用QCoreApplication::processEvents() 方法,等待消息隊列中的方法都執行完再執行。固然這是一個最基本的方法,只適用與簡單的狀況,若是事件隊列中的另外一程序也調用了該方法則會出現死鎖。同步

再看分時,它適用於可分解的操做(包括串行操做和並行操做),只需記錄當前任務的執行狀況,而後能夠再次執行。它的使用流程以下:

Function EventHandler()  
 {  
     //開始計時  
     While(執行時間 < 用戶可接受的響應時間)  
     {  
         //執行操做:     }  
    //註冊系統空閒事件以繼續處理  
 }

QT中註冊系統空閒事件的方法能夠經過QTimer::singleShot(0, this, SLOT(calculate()));將系統空閒信號註冊到本身的槽中。或者使用QMetaObject::invokeMethod(this, "calculate", Qt::QueuedConnection);方法,經過invokeMethod異步的執行某個方法。

最後重點看一下如何減小響應的時間,對於數據密集型操做,推薦使用ThreadPool來管理,減小線程上下文切換的時間;而對於IO密集型操做,則本身管理一個thread來實現,而這也是我認爲thread最應該使用的情景,即讓CPU和外設都處於滿負荷運轉狀態,減小總的操做時間。

對於並行操做響應時間的減小,在QT中引入了Qt Concurrent的概念,採用Map/Reduce的方式,具體能夠參考QT中的Concurrent Programming節。

相關文章
相關標籤/搜索