1. 程式人生 > >clock_gettime參數中不同clock ID含義的差別

clock_gettime參數中不同clock ID含義的差別

linux c clock_gettime clock_id

在分布式系統各個通信的過程中,有的應用場景需要把事件發生的時間戳放在消息中一起傳遞,接收端根據時間戳來判斷事件發生的先後順序。為此,就需要能夠獲取精確時間的函數,比如下面的代碼:

clock_gettime(CLOCK_MONOTONIC, &ts);

msg.hb_send_ts = ts;

ret_val = msg_send(dest_id, MSG_OP_HBEAT, (char *)&msg, sizeof(msg));

此外,在性能統計的過程中,我們也需要設置固定的時間間隔,以便獲取期間的運算次數或者IO數量。比如下面的代碼:

pthread_mutex_lock(&(info->stat_lock));

if (info->stat_run != 0) {

info->stat_run = 0;

clock_gettime(CLOCK_MONOTONIC, &tv);

tv.tv_sec += 1;

pthread_cond_timedwait(&(info->stat_thd_exist), &(info->stat_lock), &tv);

pthread_mutex_unlock(&(info->stat_lock));

}

上面的兩個應用場景中都用到了clock_gettime()函數,問題是這種調用方法正確麽?

這就要求對clock_gettime()的不同clk_id有深入的了解,根據個人的理解,下表列出了不同類型的區別:

技術分享

這裏需要補充的是:上面提到的NTP (NetWork Time Protocal)裏後臺會調用adjtime(),因此不收NTP影響也就不會受adjtime()函數影響。

在我們實際運行的Linux操作系統中,比如CentOS 7中, NTP服務chronyd默認會開啟,用戶可以參考下面的命令去檢查:

[[email protected] ~]# systemctl status chronyd

● chronyd.service - NTP client/server

Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)

Active: active (running) since Wed 2017-09-27 16:52:07 CST; 3h 9min ago

Main PID: 1287 (chronyd)

CGroup: /system.slice/chronyd.service

└─1287 /usr/sbin/chronyd -u chrony

Sep 27 16:52:07 localhost.localdomain systemd[1]: Starting NTP client/server...

Sep 27 16:52:07 localhost.localdomain chronyd[1287]: chronyd version 1.29.1 starting

Sep 27 16:52:07 localhost.localdomain chronyd[1287]: Linux kernel major=3 minor=10 patch=0

Sep 27 16:52:07 localhost.localdomain chronyd[1287]: hz=100 shift_hz=7 freq_scale=1.00000000 nominal_tick=10000 slew_delta_tick=833 max_tick_bias=1000 shift_pll=2

Sep 27 16:52:07 localhost.localdomain chronyd[1287]: Frequency -1.497 +/- 1.312 ppm read from /var/lib/chrony/drift

Sep 27 16:52:07 localhost.localdomain systemd[1]: Started NTP client/server.

Sep 27 16:52:17 localhost.localdomain chronyd[1287]: Selected source 120.25.115.20

在此情況下,如果clk_id使用CLOCK_MONOTONIC,顯然會受NTP的影響,這會導致時間的時間間隔不準。為此,根據上面的對比表,上面的列舉的兩個應用場景,應該使用CLOCK_MONOTONIC_RAW 。讀者,如果對具體的差異感興趣,可以在LInux下輸入man clock_gettime()查看具體的描述信息。

據此舉一反三,不但在讀取時間或時間間隔的時候,我們需要考慮到不同始終類型是否受系統時間設置函數以及NTP的影響。在調用設置時間的函數的時候,也需要考慮到對系統各種時鐘會帶來何種改變,這樣才能保證在多個軟件模塊組成的系統中,不會因為時間讀取、時鐘設置、NTP服務等帶來誤差甚至錯誤。


本文出自 “存儲之廚” 博客,請務必保留此出處http://xiamachao.blog.51cto.com/10580956/1969256

clock_gettime參數中不同clock ID含義的差別