linux 多核 系统时钟,Linux中的时间
1. Linux中time相關(guān)概念
1.1 real time
指的是實(shí)際流逝的時(shí)間,又稱(chēng)為Wall Clock Time(墻上時(shí)間)。
比如,time命令統(tǒng)計(jì)出的real time指的是該進(jìn)程從開(kāi)始運(yùn)行到運(yùn)行結(jié)束所消耗的時(shí)間。在這段時(shí)間內(nèi)不僅僅執(zhí)行了該進(jìn)程,其他進(jìn)程的時(shí)間片也得到了輪轉(zhuǎn)。
1.2 process time
指的是執(zhí)行某進(jìn)程所消耗的CPU time。CPU time指的是執(zhí)行該進(jìn)程有關(guān)代碼所花的時(shí)間,分為User CPU time和System CPU time兩部分。
User CPU time指的是在用戶(hù)態(tài)執(zhí)行該進(jìn)程的代碼所花費(fèi)的時(shí)間,不統(tǒng)計(jì)該進(jìn)程阻塞花費(fèi)的時(shí)間,也不統(tǒng)計(jì)其他進(jìn)程的時(shí)間片。
System CPU time指的是在內(nèi)核態(tài)執(zhí)行該進(jìn)程的代碼所花費(fèi)的時(shí)間,不統(tǒng)計(jì)該進(jìn)程阻塞花費(fèi)的時(shí)間,也不統(tǒng)計(jì)其他進(jìn)程的時(shí)間片。。
其實(shí),我覺(jué)得“該進(jìn)程阻塞花費(fèi)的時(shí)間”和“其他進(jìn)程的時(shí)間片” 是一個(gè)意思。因?yàn)?#xff0c;進(jìn)程阻塞時(shí),內(nèi)核會(huì)調(diào)度其他進(jìn)程執(zhí)行,所以我覺(jué)得這兩個(gè)是一個(gè)意思。
需要注意,Real time != User CPU time + System CPU time。兩個(gè)原因:
對(duì)于多核處理器上跑的多線(xiàn)程程序,會(huì)出現(xiàn)real time < User CPU time + System CPU time的情況。
畢竟計(jì)算機(jī)上不止一個(gè)進(jìn)程在跑,real time中還統(tǒng)計(jì)了其他進(jìn)程的時(shí)間片。
1.3 hardware clock
指計(jì)算機(jī)中電池供電的硬件時(shí)鐘,記錄了當(dāng)前的墻上時(shí)間,又被稱(chēng)為RTC(Real Time Clock)。內(nèi)核在啟動(dòng)時(shí)會(huì)讀取該硬件時(shí)鐘,來(lái)初始化內(nèi)核中的軟件時(shí)鐘(Software Clock)。
1.4 software clock, HZ, and jiffy
software clock指的是內(nèi)核維護(hù)的軟件時(shí)鐘。需要設(shè)置timeout的系統(tǒng)調(diào)用(例如,select,sigtimedwait)以及測(cè)量cpu time的系統(tǒng)調(diào)用(例如,getrusage)的準(zhǔn)確度(accuracy)由軟件時(shí)鐘的精度(precision / resolution)決定。
Linux內(nèi)核維護(hù)的軟件時(shí)鐘的精度是jiffy,也就是說(shuō)軟件時(shí)鐘用jiffy衡量時(shí)間。jiffy對(duì)應(yīng)的real time由內(nèi)核中的常量HZ決定,jiffy = 1 / HZ。HZ的值可人為調(diào)節(jié),可取的值在不同的內(nèi)核版本和不同的硬件平臺(tái)下也不一樣。在i386平臺(tái)下,內(nèi)核版本2.6.0后,HZ的取值可以達(dá)到1000,意味著jiffy對(duì)應(yīng)0.001秒。
那么為什么設(shè)置timeout的系統(tǒng)調(diào)用和測(cè)量cpu time的系統(tǒng)調(diào)用的準(zhǔn)確度受jiffy的限制呢?原因如下。
cpu里面有可編程間隔定時(shí)器PIT,(Programmable interval timer),目前x86-64/arm/8051-based的絕大多數(shù)cpu/mcu都是內(nèi)置PIT的,PIT以一個(gè)可調(diào)節(jié)的時(shí)間間隔,即jiffy,觸發(fā)時(shí)鐘中斷,使得操作系統(tǒng)的時(shí)鐘中斷處理程序可以可調(diào)節(jié)地周期性運(yùn)行。時(shí)鐘中斷處理程序負(fù)責(zé)維護(hù)所有的軟件定時(shí)器,在當(dāng)前進(jìn)程的時(shí)間片用光,或有定時(shí)器觸發(fā)時(shí)執(zhí)行進(jìn)程調(diào)度(線(xiàn)程調(diào)度)。時(shí)鐘中斷處理程序還負(fù)責(zé)維護(hù)軟件時(shí)鐘。因此,軟件時(shí)鐘的精度以及timer相關(guān)系統(tǒng)調(diào)用的精度都由jiffy限制。
1.5 High-resolution timers
在內(nèi)核版本2.6.21之前,timer and sleep system calls 的準(zhǔn)確度由jiffy限制。自從內(nèi)核版本2.6.21之開(kāi)始,Linux開(kāi)始支持高精度定時(shí)器(High-resolution timers, HRTs)。
在支持HRTs的系統(tǒng)上,timer and sleep system calls 的準(zhǔn)確度不再受jiffy限制,可以達(dá)到硬件級(jí)別的準(zhǔn)確度。可以通過(guò)clock_getres()返回的時(shí)鐘的精度判斷系統(tǒng)是否支持高精度定時(shí)器。
sleep system calls 包括:
1.6 Epoch
Unix系統(tǒng)使用從1970-01-01 00:00:00 +0000 (UTC)到現(xiàn)在的秒數(shù)表示時(shí)間。1970-01-01 00:00:00 +0000 (UTC)這個(gè)時(shí)間點(diǎn)稱(chēng)為Epoch。
2. 獲取時(shí)間
2.1 結(jié)構(gòu)體
目前所知,表示時(shí)間只有兩種結(jié)構(gòu)體timeval和timespec,它們的區(qū)別主要是精度不同,有些函數(shù)的參數(shù)使用timeval,有些使用timespec。
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
2.2 函數(shù)
Linux中獲取時(shí)間的函數(shù)有多種,這里我只提gettimeofday()和clock_gettime()。
2.2.1 gettimeofday()
int gettimeofday(struct timeval *tv, struct timezone *tz);
gettimeofday()是系統(tǒng)調(diào)用,用于獲取從Epoch開(kāi)始到現(xiàn)在的時(shí)間,精度是微秒。
各種資料表明,gettimeofday()讀取的是內(nèi)核中的xtime變量的值,xtime每個(gè)時(shí)鐘中斷更新一次,其精度受限于jiffy。既然是這樣,那么為什么gettimeofday()的精度是微秒呢?經(jīng)過(guò)我查閱資料,jiffy雖然會(huì)影響軟件時(shí)鐘的精度,但是gettimeofday()不是簡(jiǎn)單地讀取xtime,gettimeofday()的實(shí)現(xiàn)仍然會(huì)依賴(lài)于硬件時(shí)鐘。更具體的解釋請(qǐng)查看[7]。
我個(gè)人認(rèn)為,gettimeofday()的精度和內(nèi)核是否支持高精度定時(shí)器并沒(méi)有關(guān)系。一個(gè)是讀取時(shí)間,一個(gè)是定時(shí)器,兩者是不同的概念。查閱資料,沒(méi)發(fā)現(xiàn)有人明確講這個(gè),以后遇到了再做補(bǔ)充吧。
2.2.2 clock_gettime()
int clock_getres(clockid_t clk_id, struct timespec *res);
int clock_gettime(clockid_t clk_id, struct timespec *tp);
int clock_settime(clockid_t clk_id, const struct timespec *tp);
通過(guò)上面的接口可以訪(fǎng)問(wèn)多個(gè)時(shí)鐘,這些時(shí)鐘表示不同的含義。上面的接口中,用戶(hù)需要通過(guò)clk_id指定對(duì)哪個(gè)時(shí)鐘進(jìn)行操作。其中clock_gettime()可以獲取指定時(shí)鐘的時(shí)間,clock_getres()可以獲取指定時(shí)鐘的精度。這些時(shí)鐘的更新原理并不清楚,但是可以肯定的是,其精度和內(nèi)核是否支持高精度定時(shí)器密切相關(guān)。因?yàn)?#xff0c;多個(gè)資料提到可以使用clock_getres()得到的精度判斷內(nèi)核是否支持高精度定時(shí)器。
clk_id的值:
CLOCK_REALTIME 墻上時(shí)間,真實(shí)的時(shí)間,但是受系統(tǒng)時(shí)鐘(system clock)改變的影響,例如用戶(hù)調(diào)用adjtime函數(shù)改變了系統(tǒng)時(shí)鐘,那么該墻上時(shí)間就會(huì)隨之改變。
CLOCK_MONOTONIC 該時(shí)鐘用于測(cè)量相對(duì)的real time,該時(shí)鐘和實(shí)際的時(shí)間相同的速度流逝,并且不被系統(tǒng)時(shí)鐘(system clock)的手動(dòng)/自動(dòng)改變所影響。
CLOCK_PROCESS_CPUTIME_ID 用于測(cè)量進(jìn)程所用的CPU time。
CLOCK_THREAD_CPUTIME_ID 用于測(cè)量線(xiàn)程所用的CPU time。
int timer_create (clockid_t clockid, struct sigevent *evp, timer_t *timerid);
該系統(tǒng)調(diào)用用于創(chuàng)建定時(shí)器,參數(shù)clk_id用于指定該定時(shí)器使用的時(shí)鐘。該系統(tǒng)調(diào)用創(chuàng)建的定時(shí)器是高精度定時(shí)器。因此,我們使用clock_getres()得到的精度肯定應(yīng)該小于jiffy。這就印證了之前說(shuō)的,可以通過(guò)clock_getres()查看時(shí)鐘的精度來(lái)判斷內(nèi)核是否支持高精度定時(shí)器。我自己使用clock_getres()測(cè)試的各時(shí)鐘的精度是1ns,表示內(nèi)核支持高精度定時(shí)器。
3. 某些系統(tǒng)調(diào)用的time accuracy
sleep的參數(shù)是秒,accuracy可以達(dá)到1秒。Linux下其由nanosleep實(shí)現(xiàn),
usleep的參數(shù)是微秒,但是有人說(shuō)其accuracy不是微秒,說(shuō)它仍是由時(shí)間中斷實(shí)現(xiàn)的,本人還沒(méi)有找到資料證明usleep究竟有沒(méi)有使用HRTs。
nanosleep的參數(shù)是納秒,其由HRTs實(shí)現(xiàn),使用CLOCK_MONOTONIC測(cè)量時(shí)間,不受jiffy限制,accuracy具體可以達(dá)到多少不清楚,但是應(yīng)該可以達(dá)到微秒級(jí)別。
select的參數(shù)是微秒,別人測(cè)試accuracy可以達(dá)到微秒,有人說(shuō)其由HRTs實(shí)現(xiàn),但是本人未找到更具體的資料。
因此,選擇延時(shí)函數(shù)應(yīng)該一步到位直接用nanosleep。
4. Reference
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的linux 多核 系统时钟,Linux中的时间的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux 更改父进程名称,[Linux
- 下一篇: linux 查看系统组账号密码是什么,L