gmtime_r 使用性?
故事
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 函數系列。