erlang:now()與os:timestamp()-Erlang源碼學習一

erlang中,關於erlang:now()os:timestamp()兩個接口,查看官方文檔的解釋:

erlang:now/0
這裏寫圖片描述

os:timestamp/0
這裏寫圖片描述

按官方文檔上說erlang:now/0是廢棄了的,它可以獲取一個持續遞增的唯一時間戳。除此也沒說講到更多。

再看erlang:now/0文檔給的時間和時間修正,裏面詳細描述了erlang對於時間的處理,暫不看。

直接跳到c源碼看吧,在這之前可以看看linux內核時間的管理,明白什麼是牆上時間(wall time)、單調遞增時間(monotonic time)等。

  1. erlang:now/0
    erlang:now/0的bif函數對應erlang源碼:erts/emulator/beam/bif.c
    這裏寫圖片描述

now_0()的獲取時間調用get_now()函數,位於erts/emulator/beam/erl_time_sup.c

這裏寫圖片描述

獲取時間主要用一個回調get_time(),而獲取時間之後會與上一次調用產生的值比較,併產生一個新的保證單調遞增的唯一值,並加鎖修改舊值。關於get_time()的初始化要在同文件的erlang_init_time_sup()函數

這裏寫圖片描述

可以看到有一個條件編譯宏 ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT,在沒有配置erlang源碼時,這些宏都未定義,但如果在源碼根目錄執行了./configure配置後,會在emulator目錄生成一個文件夾(我的是x86_64-unknown-linux-gnu),裏面放有config.h配置文件,裏面根據操作系統類型做了對應宏定義,對應宏ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT就是在config.h裏,表示這個操作系統有單調遞增時間(monotonic time),那麼這裏可以看到get_time回調指向了get_os_grift_corrected_time(),此函數直接返回read_corrected_time()函數結果:

這裏寫圖片描述

可以看到read_corrected_time()函數主要執行了erts_os_monitonic_time()calc_corrected_erl_mtime()來獲取操作系統的monitonic_time以及修正時間。
erts_os_monitonic_time()直接調用posix_clock_gettime()函數,參數爲MONOTONIC_CLOCK_ID,獲取monotonic time:

這裏寫圖片描述

獲取時間的函數實則調用了linux的系統函數clock_gettime(),可以man手冊看一看;
calc_corrected_erl_time()函數:

這裏寫圖片描述

將獲取的當前操作系統monitonic time與最近一次更新的操作系統monitonic time做一個差值計算,然後根據erlang時間的設計來計算一個新的erlang monitonic time。
2. os:timestamp/0
os:timestamp()函數代碼:

這裏寫圖片描述

代碼裏調用了erts_os_system_time()函數來獲取操作系統的時間:

這裏寫圖片描述

又是熟悉的posix_clock_gettime(),並且參數爲WALL_CLOCK_ID獲取牆上時間。
3. 總結
erlang:now/0獲取的是erlang系統的monotonic time,它從操作系統獲取後還要用erlang時間處理的方式在調整爲erlang monotonic time,期間幾次會對全局變量加鎖,故效率會有損耗,而每一次獲取時間值後會與上一次獲取的值做一個對比,並加一來保證獲取值的嚴格單調遞增,所以可以用來作爲唯一名(unique name)的生成,但是,erts7.0之後就不建議用這個函數了,可以用erlang:timestamp/0替代,如果要生成唯一名可以用erlang:unique_integer/0等等。 而os:timestamp/0則是獲取操作系統的牆上時間(wall time),並做調整變爲erlang system time。

erlang:now/0獲取時間的文件爲erl_time_sup.c,所有的erlang關於時間處理方式的邏輯都定義在裏面,包括維護全局變量來處理操作系統轉變爲erlang規則的內部時間、註冊定時器週期檢查erlang時間與os時間對比的偏移量等;os:timestamp/0獲取時間的文件爲sys_time.c,是對os獲取時間的庫函數的封裝、以及對獲取的時間進行簡單調整的文件,比較輕量級。

後記:看了erlang時間的處理,感覺很有趣,後面學習一下erlang源碼中對時間的管理代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章