gmtime_r 使用性?

·

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