【问题标题】:Is standard C mktime thread safe on linux?Linux上的标准C mktime线程安全吗?
【发布时间】:2013-08-23 16:30:23
【问题描述】:

mktime 的手册页没有提到 mktime 的线程安全,但确实提到了这一点,这使它看起来像线程 unsafe

调用 mktime() 还会设置外部变量 tzname 与有关当前时区的信息。

我知道在Linux上mktime调用tzset来设置tzname,这是一个char*[]:

extern char *tzname[2];

并且 tzset 将读取环境变量 TZ 和文件 /etc/localtime.因此,除非 mktime 使用互斥锁来保护所有这些操作,否则我看不出它如何是线程安全的。

【问题讨论】:

  • @ShafikYaghmour 上一个问题及其答案集中在asctimectimegmtimelocaltime,它们返回指向静态数据的指针,因此在设计上是线程不安全的。这个问题专门针对mktime,其接口不是线程不安全的,但POSIX 额外规定的副作用可能是。因此,这不是上一个问题的重复。
  • 没错,我认为前两行添加的有点误导,上一个问题没有回答任何关于mktime的问题。
  • @user4815162342 如果 C 标准和 POSIX 冲突,那么 C standard wins。 C 标准表明 mktime 是线程安全的,因为我对我作为 dup 指出的问题的回答在最后解释。
  • @ShafikYaghmour C99 并不表示 mktime 是线程安全的,因为线程不是 C99 的一部分 - 它的状态是后续调用不会超出先前调用的结果(或,更准确地说,它没有说明这种事情可能发生)。 POSIX mktime 包含与 C99 中的功能不冲突的附加功能,因此“如果发生冲突,C 获胜”规则不适用。同样,问一下 POSIX 添加的功能是否是线程安全的也是很合理的。

标签: c linux thread-safety


【解决方案1】:

mktime确实有副作用,但副作用在大多数程序中应该是无害的。

根据POSIX,副作用就像调用了tzset,而这又只是将TZ 环境变量中的时区信息复制到C 字符串的tzname 数组中。如果您的应用程序没有更改TZ,那么同时调用mktime() 将没有问题。

除此之外,GNU libc 的tzset does use a mutex 来保护tzname 的完整性。这是标准不保证的实施质量添加。

【讨论】:

  • 好吧,但看起来 TZ 可以通过许多其他时间函数来更改,例如。 strftime,或者直接调用 tzset。此外,TZ 通常指向一个从 /etc/localtime 符号链接的文件,它也可以随时更改?
  • 抱歉没有看到你的编辑,这样更有意义,整个 tzset 调用都受到互斥锁的保护,所以任何使用时区信息的时间函数都会在互斥锁上同步,包括 strptime 和 strftime。这确实保证了线程安全,但对我来说听起来效率很低。
  • @swang tzset 有一个 fast path,如果 TZ 环境变量的值没有改变,则可以退出,尽管更改为 /etc/localtime。因此,它的效率应该是合理的。
  • 你是对的,但是由于互斥锁,低效率仍然存在,如果我有多个线程调用不同的时间函数,我将引入一个隐式同步点。我在我的应用程序上进行了 strace,确实从使用 strftime 的线程中看到了 __lll_lock_wait_private(),大概是因为调用 mktime 的一个线程正在执行 tzset_internal()。
  • @swang 根据我的经验,libc 时间函数并不是为了高效率而编写的,所以我的直觉是互斥体(尤其是在没有争议的情况下,在这种情况下它保留在用户空间中)不会引入可衡量的放缓。但是我有零数据来支持这种预感,我也没有研究过glibc私有锁的实现。
猜你喜欢
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多