資源描述:
《linux時鐘淺析》由會員上傳分享,免費在線閱讀,更多相關內(nèi)容在教育資源-天天文庫。
1、linux時鐘淺析時鐘的作用盡管與CPU指令執(zhí)行沒有什么直接關系,時鐘對于操作系統(tǒng)來說還是有著很重要的意義:1、記錄系統(tǒng)時間。很多應用程序需要知道日期和時間、由日期和時間構(gòu)成的時間戳也會被打在文件上面、等等;2、統(tǒng)計功能。如top之類的用戶程序可以查看一段時間內(nèi)的系統(tǒng)負載、以及各個進程占用CPU的時間、等等;3、定時功能。很多用戶程序會使用到定時器,比如sleep一段時間后做某件事情、比如給select設置一個超時時間、等等;關于時鐘硬件為了實現(xiàn)這些功能,計算機硬件需要提供相應的時鐘電路。這些電路大致上分兩類:1、R
2、TC(實時時鐘),記錄著當前的日期和時間(記錄的是自1970-01-01起經(jīng)歷的秒數(shù)),并且自動隨時間增長。這種硬件是由電池獨立供電的,因為它要保持日期時間的更新,不能因為計算機的斷電而停止工作。linux內(nèi)核只在啟動時從RTC獲取當前時間,用于設置系統(tǒng)時間。在系統(tǒng)時間被修改時,linux內(nèi)核會相應地更新RTC。而系統(tǒng)時間的自動增長則不依賴于RTC,依賴的是另一種時鐘電路。2、時鐘振蕩器,可以周期性地發(fā)出中斷。這種硬件是可編程的,linux內(nèi)核在啟動時可設置它發(fā)出中斷的周期,一般是1ms。于是每隔1ms,CPU將收到
3、一個時鐘中斷,這個時間間隔稱作一個tick(節(jié)拍)。利用這種周期性的中斷,linux內(nèi)核在處理時鐘中斷的中斷處理程序(參見《linux內(nèi)核中斷處理淺析》)中,實現(xiàn)了系統(tǒng)時間的自動增長、各種統(tǒng)計和定時器功能。CPU每ms都要處理一次時鐘中斷,并且還要在中斷處理程序中完成很多功能,那它還有時間干別的事嗎?考慮一個主頻為200MHz的RISC結(jié)構(gòu)的CPU,假設每個CPU周期能處理一條指令,那么1ms的時間這個CPU能執(zhí)行約20萬條指令。假設時鐘中斷處理程序能在1萬條指令之內(nèi)完成(一般情況下1萬條指令應該足夠了),CPU還是
4、有大部分的時間能干其他事的。關于時鐘中斷在單處理器系統(tǒng)中,每個tick只發(fā)生一次時鐘中斷。在對應的中斷處理程序中完成更新系統(tǒng)時間、統(tǒng)計、定時器、等全部功能;而在多處理器系統(tǒng)下,時鐘中斷實際上是分成兩個部分:1、全局時鐘中斷,系統(tǒng)中每個tick只發(fā)生一次。對應的中斷處理程序用于更新系統(tǒng)時間和統(tǒng)計系統(tǒng)負載;2、本地時鐘中斷,系統(tǒng)中每個tick在每個CPU上發(fā)生一次。對應的中斷處理程序用于統(tǒng)計對應CPU和運行于該CPU上的進程的時間,以及觸發(fā)對應CPU上的定時器;于是,在多處理器系統(tǒng)下,每個tick,每個CPU要處理一次本
5、地時鐘中斷;另外,其中一個CPU還要處理一次全局時鐘中斷。更新系統(tǒng)時間在linux內(nèi)核中,全局變量jiffies_64用于記錄系統(tǒng)啟動以來所經(jīng)歷的tick數(shù)。每次進入時鐘中斷處理程序(多處理器系統(tǒng)下對應的是全局時鐘中斷)都會更新jiffies_64的值,正常情況下,每次總是給jiffies_64加1。而時鐘中斷存在丟失的可能。內(nèi)核中的某些臨界區(qū)是不能被中斷的,所以進入臨界區(qū)前需要屏蔽中斷。當中斷屏蔽取消的時候,硬件只能告訴內(nèi)核是否曾經(jīng)發(fā)生了時鐘中斷、卻不知道已經(jīng)發(fā)生過多少次。于是,在極端情況下,中斷屏蔽時間可能超過1
6、個tick,從而導致時鐘中斷丟失。如果計算機上的時鐘振蕩器有很高的精度,linux內(nèi)核可以讀振蕩器中的計數(shù)器,通過比較上一次讀的值與當前值,以確定中斷是否丟失。如果發(fā)現(xiàn)中斷丟失,則本次中斷處理程序會給jiffies_64增加相應的計數(shù)。但是如果振蕩器硬件不允許(不提供計數(shù)器、或者計數(shù)器不允許讀、或者精度不夠),內(nèi)核也沒法知道時鐘中斷是否丟失了。(不過丟失就丟失吧,也沒什么大不了的。)內(nèi)核中的全局變量xtime用于記錄當前時間(自1970-01-01起經(jīng)歷的秒數(shù)、本秒中經(jīng)歷的納秒數(shù))。xtime的初始值就是內(nèi)核啟動時從
7、RTC讀出的。在時鐘中斷處理程序更新jiffies_64的值后,便更新xtime的值。通過比較jiffies_64的當前值與上一次的值(上面說到,差值可能大于1),決定xtime應該更新多少。系統(tǒng)調(diào)用gettimeofday(對應庫函數(shù)time和gettimeofday)就是用來讀xtime變量的,從而讓用戶程序獲取系統(tǒng)時間。統(tǒng)計系統(tǒng)負載在時鐘中斷處理程序(多處理器系統(tǒng)下對應的是全局時鐘)完成對上述jiffies_64和xtime的更新之后,接下來就會對系統(tǒng)負載進行統(tǒng)計。所謂系統(tǒng)負載,是指系統(tǒng)中各個CPU的可執(zhí)行隊列
8、中包含的進程數(shù)目。值為0表示對應CPU上沒有可執(zhí)行的進程,CPU空閑;值為1表示對應CPU被一個進程獨占,CPU占用率為100%;值大于1表示對應CPU被多個進程共享,CPU占用率為100%?,F(xiàn)在,內(nèi)核要在中斷處理程序中統(tǒng)計系統(tǒng)負載,意味著內(nèi)核每隔一個tick要去查看一下在當前時間點上各個CPU的可執(zhí)行隊列中的進程數(shù)目。實際上,孤立地看每個ti