我很惊讶地看到gmtime_r真的在呼叫tz-任何东西。我认为存在本地时间vs gmtime的原因是前者可以进行tz转换,而后者则不需要。看起来gmtime会调用__tz_convert,然后继续并在tz上获取全局锁(甚至根本不需要...对吗?) 我在这里想念什么吗? 如何在多线程应用程序中高效地转换epoch-> struct tm?
(gdb) where
#0 0x00007fffee255eec in __lll_lock_wait_private () from /lib64/libc.so.6
#1 0x00007fffee2007bc in _L_lock_2546 () from /lib64/libc.so.6
#2 0x00007fffee2005f7 in __tz_convert () from /lib64/libc.so.6
#3 0x000000000041c63f in DateTimeEx (dt=..., this=0x7fffca551900) at /var/lib/jenkins/workspace/hfalgo_src_hotfix_1.69.1-T6J4HNFQDMYVEKV4MEGVD6UCCPG7KHWQDOSVYBUDROFXZA6YINSA/hfalgo_src/./core/Time.h:81
答案 0 :(得分:1)
glibc可以处理包含leap秒信息的时区数据库文件,并且gmtime
和gmtime_r
会考虑这些leap秒。 (例如,Debian tzdata
软件包在/usr/share/zoneinfo/right
目录中提供了此类时区文件。)这就是为什么glibc实现读取时区数据库并执行与此相关的一些锁定的原因。
我不知道有人实际使用the秒功能。 POSIX当前要求从纪元开始的计数不考虑任何leap秒,因此,使用带有leap秒的数据文件会导致诸如gmtime
之类的功能出现不一致的行为。
但是,我希望某些不可移植的软件依赖于这样的事实,即调用gmtime
或gmtime_r
会执行隐式tzset
调用,从而初始化tzname
和其他全局变量变量。这是从当前实现中消除锁定的更大障碍。 (有人甚至为此悬赏,但100美元的价格与解决此问题所需的努力完全不成比例。)
如果您今天需要避免锁定,则需要查找gmtime
算法(