天天看點

《Unix/Linux系統程式設計》第五章學習筆記

《Unix/Linux系統程式設計》第五章學習筆記
本章讨論了定時器和定時器服務﹔介紹了硬體定時器的原理和基于Intel x86的PC中的硬體定時器;講解了CPU操作和中斷處理;描述了Linux中與定時器相關的系統調用、庫函數和定時器服務指令;探讨了程序間隔定時器、定時器生成的信号,并通過示例示範了程序間隔定時器。程式設計項目的目的是要在一個多任務處理系統中實作定時器、定時器中斷和間隔定時器。

定時器是由時鐘源和可程式設計計數器組成的硬體裝置。時鐘源通常是一個晶體振蕩器,會産生周期性電信号,以精确的頻率驅動計數器。使用一個倒計時值對計數器進行程式設計,每個時鐘信号減1。當計數減為0時,計數器向CPU生成一個定時器中斷,将計數值重新加載到計數器中,并重複倒計時。計數器周期稱為定時器刻度,是系統的基本計時單元。

基于Intel x86的個人計算機有數個定時器(Bovet和 Cesati 2005).

(1)實時時鐘(RTC):RTC由一個小型備用電池供電。即使在個人計算機關機時,它也能連續運作。它用于實時提供時間和日期資訊。當Linux啟動時,它使用RTC更新系統時間變量,以與目前時間保持一緻。在所有類Unix系統中,時間變量是一個長整數,包含從1970年1月1日起經過的秒數。

(2)可程式設計間隔定時器(PIT)(Wang2015):PIT是與CPU分離的一個硬體定時器。可對它進行程式設計,以提供以毫秒為機關的定時器刻度。在所有IO裝置中,PIT可以最高優先級IRQ0中斷。PIT定時器中斷由Linux核心的定時器中斷處理程式來處理,為系統操作提供基本的定時單元,例如程序排程、程序間隔定時器和其他許多定時事件。

(3)多核CPU中的本地定時器(Intel1997;Wang2015):在多核CPU中,每個核都是一個獨立的處理器,它有自已的本地定時器,由 CPU時鐘驅動。

(4)高分辨率定時器;大多數電腦都有一個時間戳定時器(TSC),由系統時鐘驅動。它的内容可通過64位TSC寄存器讀取。由于不同系統主機闆的時鐘頻率可能不同,TSC不适合作為實時裝置,但它可提供納秒級的定時器分辨率。一些高端個人計算機可能還配備有專用高速定時器,以提供納秒級定時器分辨率。

每個CPU都有一個程式計數器(PC),也稱為指令指針(IP),以及一個标志或狀态寄存器(SR)、一個堆棧指針(SP)和幾個通用寄存器,當PC指向記憶體中要執行的下一條指令時,SR包含CPU的目前狀态,如操作模式、中斷掩碼和條件碼,SP指向目前堆棧棧頂。堆棧是CPU用于特殊操作(如 push、pop調用和傳回等)的一個記憶體區域。CPU操作可通過無限循環進行模組化。

外部裝置(如定時器)的中斷被饋送到中斷控制器的預定義輸入行,按優先級對中斷輸入排序,并将具有最高優先級的中斷作為中斷請求(IRQ)路由到 CPU。對于每個中斷,可以程式設計中斷控制器以生成一個唯一編号,叫作中斷向量,辨別中斷源。在擷取中斷向量号後,CPU用它作為記憶體中中斷向量表(AMD64 20I1)中的條目索引,條目包含一個指向中斷處理程式入口位址的指針來實際進行中斷。當中斷處理結束時,CPU恢複指令的正常執行。

在linux下,常用的擷取時間的函數有如下幾個:

   asctime, ctime, gmtime, localtime, gettimeofday ,

  mktime, asctime_r, ctime_r, gmtime_r, localtime_r

1)time() 函數擷取目前時間

(2)localtime_r() localtime()取得當地目前時間和日期

函數原型如下:

(3)asctime() asctime_r() 将時間和日期以字元串格式傳回‘

(4) ctime(),ctime_r() 将時間和日期以字元串格式表示

(6)gettimeofday() 擷取目前時間

定時器計時,并向程序生成一個信号。作業系統核心不必使用額外的資料結構來處理程序的VIRTUAL 和 PROF定時器。但是,REAL模式間隔定時器各不相同,因為無論程序是否正在執行,它們都必須由定時器中斷處理程式來更新。是以,作業系統核心必須使用額外的資料結構來處理程序的 REAL 模式定時器,并在定時器到期或被取消時采取措施。在大多數作業系統核心中,使用的資料結構都是定時器隊列。我們将在本章末尾解釋程式設計項目中的定時器隊列。

在基本代碼系統中,隻有一種執行實體,即任務,一次隻執行一個任務。某任務在收到切換指令、進入休眠或退出之前,會一直執行下去。此外,任務切換隻會發生在操作結束時,而不會發生在任何操作過程中。是以,任務之間沒有競争,是以在基本代碼系統中沒有臨界區。但是,一旦我們将中斷引人系統,情況就會改變。有兩種類型的實體來執行中斷,分别是任務和中斷處理程式,它們可能會争奪系統中的同一(共享)資料對象。例如,當某任務請求間隔定時器時,必須将請求作為定時器隊列元素輸入timerQueue中。當某任務修改timerQueue 時,如果出現定時器中斷,它将轉移任務以執行中斷處理程式,可能會改動同一 timerQueue,造成競态條件。是以,timerQueue是臨界區,必須對它進行保護,以確定它一次隻能由一個執行實體通路。同樣,當某程序在sleep()函數過程中執行時,可能被轉移到執行中斷處理程式,即可執行wakeup(),以試圖在程序完成休眠操作之前喚醒它,進而導緻另一個竟态條件。是以,問題是如何防止任務和中斷處理程式互相幹擾。

time()擷取目前時間

點選檢視代碼

《Unix/Linux系統程式設計》第五章學習筆記
《Unix/Linux系統程式設計》第五章學習筆記

gettimeofday() 擷取目前時間

《Unix/Linux系統程式設計》第五章學習筆記
《Unix/Linux系統程式設計》第五章學習筆記
《Unix/Linux系統程式設計》第五章學習筆記
《Unix/Linux系統程式設計》第五章學習筆記