最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux時間子系統(tǒng)之時間的表示示例詳解

 更新時間:2020年05月12日 09:07:19   作者:Roland_Sun  
這篇文章主要給大家介紹了關(guān)于Linux時間子系統(tǒng)之時間的表示的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用linux系統(tǒng)具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

在Linux內(nèi)核中,為了兼容原有的代碼,或者符合某種規(guī)范,并且還要滿足當(dāng)前精度日益提高的要求,實現(xiàn)了多種與時間相關(guān)但用于不同目的的數(shù)據(jù)結(jié)構(gòu):

1)jiffies和jiffies_64

內(nèi)核用jiffies_64全局變量記錄系統(tǒng)自啟動以來經(jīng)過了多少次Tick。它的聲明如下(代碼位于kernel/time/timer.c中):

__visible u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;

EXPORT_SYMBOL(jiffies_64);

可以看出來jiffies_64被定義成了64位無符號整數(shù)。但是,由于歷史的原因,內(nèi)核源代碼中還包含了另一個叫做jiffies的變量。jiffies的引用(代碼位于include/linux/jiffies.h中)申明為:

extern u64 __cacheline_aligned_in_smp jiffies_64;
extern unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data jiffies;

因此,jiffies變量是一個unsigned long類型的全局變量,如果在32位處理器上只有4個字節(jié)長(32位)。但是,如果在64位處理器上也有8個字節(jié)長(64位),這時候jiffies和jiffies_64兩個全局變量是完全等價的。

但是翻遍所有代碼你也找不到全局變量jiffies的定義,最終在內(nèi)核的鏈接腳本中(對于Arm64架構(gòu)來說腳本位于arch/arm64/kernel/vmlinux.lds.S中)找到了下面這行:

jiffies = jiffies_64;

玄機在這里,原來在鏈接的時候指定了符號jiffies和jiffies_64指向同一個地址。也就是說,在32位機器上,jiffies和jiffies_64的低4個字節(jié)是一樣的。

一般情況下,無論在32位或64位機器上,我們都可以直接訪問jiffies全局變量,但如果要獲得jiffies_64全局變量,則需要調(diào)用get_jiffies_64函數(shù)。對于64位系統(tǒng)來說,兩者一樣,而且jiffies被申明成了volatile的且是Cache對齊的,因此只需要直接返回jiffies就好了:

static inline u64 get_jiffies_64(void)
{
 return (u64)jiffies;
}

而對于32位系統(tǒng)來說,由于其對64位讀寫不是原子的,所以還需要持有jiffies_lock讀順序鎖:

u64 get_jiffies_64(void)
{
 unsigned int seq;
 u64 ret;

 do {
 seq = read_seqbegin(&jiffies_lock);
 ret = jiffies_64;
 } while (read_seqretry(&jiffies_lock, seq));
 return ret;
}

jiffies基本上是每一次Tick到來都會加1的,而Tick的周期HZ是由內(nèi)核編譯選項配置的。在32位系統(tǒng)中,我們假設(shè)HZ被設(shè)置成了250,那么每個Tick的周期就是4毫秒,那么該計數(shù)器將在不到200天后達(dá)到最大值后溢出。如果HZ被設(shè)置的更高,那這個溢出時間會更短。當(dāng)然,如果在64位系統(tǒng)中,則完全不用考慮這個問題。因此,在用jiffies進(jìn)行時間比較的時候,需要用系統(tǒng)已經(jīng)定義好的幾個宏:

time_after(a,b)
time_before(a,b)
time_after_eq(a,b)
time_before_eq(a,b)
time_in_range_open(a,b,c)
time_is_before_jiffies(a)
time_is_after_jiffies(a)
time_is_before_eq_jiffies(a)
time_is_after_eq_jiffies(a)

為了保險起見,內(nèi)核也提供了對應(yīng)的64位版本。這些宏可以有效的解決回繞問題,不過也不是無限制的。具體是怎么做到的呢?我們挑一個time_after宏來看看就知道了:

#define time_after(a,b) \
 (typecheck(unsigned long, a) && \
 typecheck(unsigned long, b) && \
 ((long)((b) - (a)) < 0))

先是對兩個變量做類型檢查,必須都是unsigned long型的。最重要的是后面,先將兩個無符號長整形相減,然后將他們變成有符號的長整型,再判斷其是否為負(fù)數(shù),也就是32位的最高位是否為1。

為什么這樣可以部分解決所謂回繞的問題呢?我們可以舉個例子,為了簡單起見,以8位無符號整數(shù)為例,其取值范圍是0到255(0xFF)。假設(shè)當(dāng)前時間是250,那么過5個Tick之后,就是255了,已經(jīng)到達(dá)了能表達(dá)的最大值。這時,如果再過一個Tick,也就是6個Tick之后,就將會溢出變成0了。此時,如果簡單的通過對兩個值的比較來判斷哪個時間再后面的話,顯然就要出錯了,因為過了6個Tick之后的時間是0,反而小于當(dāng)前的時間,這個問題就是所謂的回繞。但是,如果我們先將這兩個數(shù)相減,也就是0-250(0-0xFA),也會產(chǎn)生溢出,最終得到的數(shù)剛好是6。但這也是有限制的,兩個比較的時間之間的差值不能超過最大表示范圍的一半。假設(shè)現(xiàn)在的時間還是250,而過了128個Tick之后,時間值將變成122,再將兩者相減的話就是122-250(0x86-0xFA),減出來的數(shù)字就是128了,此時轉(zhuǎn)成有符號數(shù)就變成負(fù)數(shù)了,結(jié)果就錯了。

另外,jiffies是每個Tick更新一次的,而Tick的周期又是編譯的時候定義好的,所以可以將jiffies的數(shù)值轉(zhuǎn)換成具體過了多少時間,反之亦然。因此,內(nèi)核提供了如下轉(zhuǎn)換函數(shù):

unsigned int jiffies_to_msecs(const unsigned long j);
unsigned int jiffies_to_usecs(const unsigned long j);
unsigned long msecs_to_jiffies(const unsigned int m);
unsigned long usecs_to_jiffies(const unsigned int u);

2)timespec和timespec64

timespec由秒和納秒組成,其定義如下(代碼位于include/uapi/linux/time.h):

struct timespec {
 __kernel_time_t tv_sec;
 long tv_nsec;
};

tv_sec:存放自1970年1月1日0時(UTC時間)以來經(jīng)過的秒數(shù)。__kernel_time_t最終定義成了long型,也就是在32位系統(tǒng)上是32位長,而在64位系統(tǒng)上是64位長。

tv_nsec:存放自上一秒開始經(jīng)過的納秒(ns)數(shù)。

timespec還有一個64位的擴展結(jié)構(gòu),其定義如下(代碼位于include/linux/time64.h):

typedef __s64 time64_t;

......

struct timespec64 {
 time64_t tv_sec;
 long tv_nsec;
};

這個結(jié)構(gòu)體中的變量定義和timespec一樣,只不過tv_sec的類型一定是64位無符號數(shù)。所以,也就是說在64位系統(tǒng)上,timespec和timespec64結(jié)構(gòu)體是一模一樣的。

3)ktime_t

在Linux的時間子系統(tǒng)內(nèi),一般使用ktime_t來表示時間,其定義如下(代碼位于include/linux/ktime.h):

typedef s64 ktime_t;

就是一個非常簡單的64位帶符號整數(shù),表示的時間單位是納秒。

4)timeval

gettimeofday和settimeofday函數(shù)使用timeval作為時間單位:

struct timeval {
 __kernel_time_t tv_sec;
 __kernel_suseconds_t tv_usec;
};

tv_sec:存放自1970年1月1日0時(UTC時間)以來經(jīng)過的秒數(shù)。__kernel_time_t最終定義成了long型,也就是在32位系統(tǒng)上是32位長,而在64位系統(tǒng)上是64位長。

tv_usec:__kernel_suseconds_t實際最終也被定義成了long型,存放自上一秒開始經(jīng)過的微秒(us)數(shù)。

所以,這個結(jié)構(gòu)體其實和timespec結(jié)構(gòu)體大同小異,tv_sec存的值是一樣的,而只需要將timespec中的tv_nsec除以1000就是timeval中的tv_usec。

總結(jié)

到此這篇關(guān)于Linux時間子系統(tǒng)之時間的表示的文章就介紹到這了,更多相關(guān)Linux時間的表示內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • .htaccess設(shè)置指南經(jīng)典說明

    .htaccess設(shè)置指南經(jīng)典說明

    .htaccess 會降低APACHE的性能,除非你對目錄權(quán)限要求很高或需要做UrlRewrite,否則不推薦你使用.
    2008-04-04
  • Centos7 Mysql 5.6 多主一從 解決方案與詳細(xì)配置

    Centos7 Mysql 5.6 多主一從 解決方案與詳細(xì)配置

    這篇文章主要介紹了Centos7 Mysql 5.6 多主一從 解決方案與詳細(xì)配置,需要的朋友可以參考下
    2016-04-04
  • 淺談Linux下免密碼切換到root用戶當(dāng)注意的問題

    淺談Linux下免密碼切換到root用戶當(dāng)注意的問題

    下面小編就為大家?guī)硪黄獪\談Linux下免密碼切換到root用戶當(dāng)注意的問題。小編覺得挺不錯的?,F(xiàn)在就分享給大家。也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • Linux文件查找命令總結(jié)(上篇)

    Linux文件查找命令總結(jié)(上篇)

    這篇文章主要介紹了Linux文件查找命令總結(jié)(上篇),本文章內(nèi)容詳細(xì),通過案例可以更好的掌握文件查找的相關(guān)命令,本篇為上篇,需要的朋友可以參考下
    2023-01-01
  • Linux tr命令的使用

    Linux tr命令的使用

    這篇文章主要介紹了Linux tr命令的使用,幫助大家更好的理解和學(xué)習(xí)Linux,感興趣的朋友可以了解下
    2020-08-08
  • 詳解linux下umask的使用

    詳解linux下umask的使用

    這篇文章主要介紹了詳解linux下umask的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Linux的文件描述符、文件指針、索引節(jié)點詳情

    Linux的文件描述符、文件指針、索引節(jié)點詳情

    這篇文章主要對Linux的文件描述符、文件指針、索引節(jié)點詳情介紹,感興趣和需要的朋友可以參考下文
    2021-08-08
  • Linux下如何高效切換目錄的方法

    Linux下如何高效切換目錄的方法

    這篇文章主要介紹了Linux下如何高效切換目錄,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Linux修改主機名命令詳解

    Linux修改主機名命令詳解

    在本篇文章里小編給大家整理的關(guān)于Linux修改主機名命令的知識點詳解,有興趣的朋友可以參考學(xué)習(xí)下。
    2020-02-02
  • linux Dig命令使用大全

    linux Dig命令使用大全

    這篇文章主要介紹了linux Dig命令使用大全,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01

最新評論

奉化市| 定结县| 大方县| 张家港市| 曲靖市| 增城市| 藁城市| 永定县| 青海省| 邯郸市| 于田县| 花莲市| 正定县| 漳平市| 嘉鱼县| 潢川县| 延吉市| 曲水县| 安岳县| 嘉禾县| 辽源市| 建宁县| 苏尼特左旗| 班玛县| 皮山县| 沁源县| 辉县市| 高平市| 新宾| 蒲城县| 双辽市| 武城县| 雷波县| 德格县| 会泽县| 麟游县| 增城市| 东莞市| 浦北县| 和顺县| 剑川县|