Qt QElapsedTimer 計時器


  QElapsedTimer提供了一種快捷的計算流逝時間的方法。它通常被用來計算兩個事件或操作之間過去了多久。並且,該類的方法非常類似於我們之前講過的QTime類的三個計時函數,所以,我們可以很快速的在使用這兩個類的代碼之間進行移植。但是,不像QTime,QElapsedTimer會盡可能的使用某種單調時鍾。這也就意味着,沒辦法將QElapsedTimer對象轉換成人類可讀的時間格式。

  這個類的典型使用方法就是測量一個耗時操作花了多少時間。最簡單的例子如下:

1 QElapsedTimer timer; 2 timer.start(); 3 slowOperation1(); 4 qDebug() << "The slow operation took" << timer.elapsed() << "milliseconds";

  在這個例子中,我們下定義了一個QElapsedTimer的對象,然后調用它的start() 方法開始計時,完成一個耗時操作后,再調用它的elapsed() 方法,得到耗時操作所花費的具體時間,以毫秒計算。

  我們也可以在一個耗時操作完成后,通過elapsed() 函數的返回值來決定下一個耗時操作可以運行的時間。這對於需要在一定的時間周期內完成幾個耗時操作來說是至關重要的。比如下面代碼所展現的案例:

 1 void executeSlowOperations(int timeout)  2 {  3  QElapsedTimer timer;  4  timer.start();  5  slowOperation1();  6   
 7     int remainingTime = timeout - timer.elapsed();  8     if (remainingTime > 0)  9  slowOperation2(remainingTime); 10 } 

  另一個QElapsedTimer的使用案例是,一個具體的操作需要運行一定的時間長度。對於這種需求,QElapsedTimer提供了hasExpired() 函數,這個函數可以判斷自從上次調用start() 或restart() 之后,是否過去了多少毫秒。如下代碼所示:

1 void executeOperationsForTime(int ms) 2 { 3  QElapsedTimer timer; 4  timer.start(); 5   
6     while (!timer.hasExpired(ms)) 7  slowOperation1(); 8 }

  上面我們說,QElapsedTimer會使用運行平台所支持的某種單調參考時鍾。這具有額外的好處,它可以使QElapsedTimer不受系統時間調整的影響,也不受系統時區設置的影響。當然,相對的,這也意味着我們只能把QElapsedTimer的值和那些使用了同樣參考時鍾的值相比較。特別是,當我們把QElapsedTimer的自從參考點以來的值序列化到某個變量中后,更應該注意這點。並且,不應該把這些值通過網絡進行交換或存儲到磁盤,因為無法保證接收端的計算機和產生該值的計算機是否使用同一種參考時鍾和參考點,也無法保證其自從參考點以來是否發生過重啟。但是,我們可以將這些值在運行在同一太機器上的不同進程間進行交換,條件是他們都使用相同的參考時鍾。QElapsedTimer在同一台機器上總是使用相同的參考時鍾,所以,在一個進程中比較來自另一個進程的QElapsedTimer值是安全的。

  注意,QElapsedTimer所使用的時鍾類型,有一些是有范圍限制的,通常是32-bit,當達到上限時會發生溢出。QElapsedTimer會處理這種情況並提供一致時間。但是,當從QElapsedTimer中提取時間時,同一機器上的兩個不同的進程會對實際逝去的時間有不同的理解。

 

下面,我們就來具體看下QElapsedTimer所使用的集中時鍾類型:

SystemTime

     該類型的時鍾是唯一一種表示實時時間的時鍾,它表示子1970.1.1零點以來的毫秒數。它就相當於C或POSIX中的time() 函數,外加毫秒值。這種時鍾類型目前只用於不支持 單調時鍾的Unix系統。它也是QElapsedTimer可能使用的唯一一種非單調時鍾。

MonotonicClock

   表示系統的單調時鍾,表示的是自過去任意時間點以來的毫秒數。這種時鍾類型用於支持POSIX時鍾類型的Unix系統(_POSIX_MONOTONIC_CLOCK)。並且,這種時鍾類型不會發生溢出。

TickCounter

   這種時鍾類型的計時基於系統的或處理器的tick數,然后再乘以一個tick的周期。這種時鍾類型用於Windows系統。並且,當高精度的性能計數器可用時,會自動使用PerformanceCounter替代這種時鍾類型。TickCounter是唯一一種可能發生溢出的時鍾類型。但在Windows Vista 和 Windows server 2008上,由於它們支持擴展的64-bit  tick  counter,可以避免溢出。

   在Windows平台,時鍾會在2^32毫秒,即大約49.7天后溢出。這也意味着兩個不同的進程通過乘以2^32毫秒來計算逝去的時間,得到的結果可能是不同的。當進行這類數值得比較時,我們建議將毫秒的高32位屏蔽掉。

MachAbsoluteTime

    這種時鍾類型是基於Mach kernels 表示的絕對時間,例如 OS X。把這種時鍾類型和MonotonicClock區分開是因為OS X 和 IOS也是Unix系統,也可能支持一種和Mach絕對 時間具有不同值的POSIX單調時鍾。這種時鍾是單調的並且不會發生溢出。

PerformanceCounter

    這種時鍾類型使用Windows的QueryPerformanceCounter() 和 QueryPerformanceFrequency() 函數訪問系統的高精度性能計數器。但因為這種計數器並不是在所有平台上都可用,所以,QElapsedTimer會在該時鍾類型不可用時,自動使用TickCounter作為替代。這種時鍾類型也是單調的並且不會發生溢出。

   搞明白每一種可用的時鍾類型和單調性后,我們可以在程序中使用clockType() 函數來獲得一個QElapsedTimer對象所使用的底層時鍾類型;使用isMonotonic() 函數判斷一個QElapsedTimer對象的單調性。

   最后,至於該類的使用方式,上面的例子也說的差不多了,最常用的就是start()、restart()、elapsed()這些函數。其他的函數,大家在需要時可以參考Qt幫助文檔。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM