Qt 如何正確的讓程序睡眠

Qt框架是Symbian應用程序開發和MeeGo應用程序開發的主要框架,我們在編寫Qt程序時經常會遇到這樣的需求: 讓程序等待一段時間, 這段時間裏可能程序什麼都不做, 也可能是在後臺開了個子線程在做一些用戶看不見的工作。

首先我們容易想到的方法是使用類似linux提供的”sleep”或”usleep”函數。 但用過這組函數的Qter都知道, 這組函數會將你當前的線程/進程變爲“睡眠”狀態。 這個“睡眠”是深度意義的睡眠, 睡眠期間內核不會分配給程序時間片, 所以程序什麼都不做, 更不用提界面的刷新了。 直接導致的問題就是用戶無法與程序交互。 所以說直接使用sleep函數睡眠是常見的錯誤方案之一。

另外一種更常見的錯誤方法是使用QTimer+死循環。 類似下面的代碼:

  1. QTimer t; 
  2. t.start(); 
  3. while(t.elapsed() < 250); 

這個簡單粗暴的解決方案也是行不通的。 從代碼中我們可以發現在while循環中不停的調用elapsed()函數, 等於在這段時間內CPU完全沒有機會做別的什麼事情。 特別是在Linux這樣非搶佔式的操作系統中, 這樣的死循環造成的影響是致命的, CPU被完全佔用, 內核都沒有機會調度進程, 別的程序拿不到時間片執行, 系統基本上就是癱瘓狀態了。 無論如何, 這種結果都不是我們想要的。(當然拉, 除非你想寫的是病毒程序。) 對於我們的程序本身, 雖然它佔用了所有的CPU, 但由於它陷入該循環, 程序沒有機會進入到GUI事件循環, 導致同樣界面是無法刷新的。

其實把上面的代碼稍加改變就能得到一個很好的解決方案。 第一步, 解決界面無法刷新的問題。 調用QCoreApplication::processEvents(), 代碼如下:

  1. QTimer t; 
  2. t.start(); 
  3. while(t.elapsed() < 250
  4. QCoreApplication::processEvents(); 

第二步, 解決程序CPU佔用率過高的問題 -- 讓程序適當睡眠。

  1. QTimer t; 
  2. t.start(); 
  3. while(t.elapsed() < 250
  4. QCoreApplication::processEvents(); 
  5. usleep(10000);//sleep和usleep都已經obsolete,建議使用nanosleep代替 

這裏設置程序睡眠一段很短很短的時間, 對於用戶來說是不會有什麼感覺的, 但對內核來說就意義大不同。 這樣內核就有充足的時間調度進程/線程, 讓其他程序有機會執行。

在Qt裏其實是提供了類似的API的, 只是不在core或gui庫裏, 而是在QTestLib中。 參考下面的文檔:http://doc.qt.nokia.com/4.6/qtest.html#qWait

這個函數是專爲Qt測試提供, 所以不建議直接使用在Qt程序中。 不過它的基本實現差不多就是我們上面列出的代碼, 很簡單, copy paste到程序裏用就好了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章