Skip to main content

Command Palette

Search for a command to run...

gmtime_r 使用性?

Updated
1 min read

故事

gmtime_r 很坑。

會用到 gmtime_r 的多少是因為 gmtime 不是 thread-safe 的,但又需要 threading 來增加效率。

但假如使用者會很頻繁的呼叫他,那就可能要考慮其他函數。

為什麼?

gmtime_r 的運作

gmtime_r 的功能是把 Unix timestamp 轉換出 CST+0 時區的年月日時分秒以及其他資訊(如星期)。這個函數事實上會和 localtime_r 共用一個計算時間的函數。

這就是主要的問題,localtime_r 會需要用到時區資料,而【時區訊息與時間差】的資料並不是一直不變,由於夏令時間,這東西至少每年要更動兩次。

這函數在計算前,會先去打開某個檔案,然後去更新一個全域變數。

用來參考的 Source Code

/* Update internal database according to current TZ setting.
   POSIX.1 8.3.7.2 says that localtime_r is not required to set tzname.
   This is a good idea since this allows at least a bit more parallelism.  */
  tzset_internal (tp == &_tmbuf && use_localtime);

沒錯,會去修改全域變數,然後又保證 thread-safe,那通常就有 Lock ,除非是 atomic 修改。

很直接的驗證方式,就是直接開一堆 Thread 去呼叫函數, htop 就可以看到近乎一半的 kernel mode,消耗時間也會隨開的 Thread 的數量快速增長。

可能的取代品

假如要保證 thread-safe ,又不希望有 Lock 影響到效能,可以考慮使用 Boost 的 Posix Time 函數系列。

Reference

More from this blog

簡介 C++ 的 Type Erase (用多型和模板做 Duck Type)

起點 讓我們先從 template 出發:foo 需要一個 callback function。 template<typename Func> void foo(Func callback) { // ... callback(); } 但是這會讓編譯錯誤訊息有點模糊:假如 callback 並不是一個可以呼叫的函數指標,或者並不是一個 callable object ,那編譯器會說錯出在第四行。但是我們都希望,編譯器在呼叫函數時就幫我們指出:這不是 foo 想要的 call...

May 14, 20243 min read

帕秋莉的魔法筆記

45 posts

後端工程師。

不定時張貼一些寫扣時的筆記。

gmtime_r 使用性?