为什么 glibc(可能还有其他)static tm struct 不是本地线程?
Why is glibc (and maybe others) static tm struct not thread local?
今天进行同行评审也是如此,有人以 tm tm = *gmtime(&t)
的形式抱怨 gmtime 的使用。我的假设一直是它会使用每线程存储来确保安全,但环顾四周似乎 time/localtime.c
只是将其声明为常规全局。
/* The C Standard says that localtime and gmtime return the same pointer. */
struct tm _tmbuf;
如果我理解正确的话,这会使该实现在现代系统上完全崩溃,因为可靠地告诉其他线程在做什么是不切实际的?
为什么它不是按线程制作的,以使其尽可能安全?
我当然知道这个函数还有其他版本(虽然不可移植),所以一个简单的 mygmtime 包装器是可能的,但看起来很奇怪这仍然是一个突出的问题。
你说得对 gmtime()
和 localtime()
函数不是线程安全的。 C 库中有不少这样的函数,它们之所以如此,是因为它们是为单线程程序设计的(曾经是唯一一种),将它们更改为依赖线程本地数据将是一种改动到他们先前定义的语义。它们不是 "totally broken" 因为许多程序只使用一个线程,并且因为只要小心使用它们也可以用于多线程程序。
话虽如此,这些是可重入版本已经标准化的众多功能之一(gmtime_r()
和 localtime_r()
);如果您可以使用可重入版本,那么它们是多线程程序的更好选择。
今天进行同行评审也是如此,有人以 tm tm = *gmtime(&t)
的形式抱怨 gmtime 的使用。我的假设一直是它会使用每线程存储来确保安全,但环顾四周似乎 time/localtime.c
只是将其声明为常规全局。
/* The C Standard says that localtime and gmtime return the same pointer. */
struct tm _tmbuf;
如果我理解正确的话,这会使该实现在现代系统上完全崩溃,因为可靠地告诉其他线程在做什么是不切实际的?
为什么它不是按线程制作的,以使其尽可能安全?
我当然知道这个函数还有其他版本(虽然不可移植),所以一个简单的 mygmtime 包装器是可能的,但看起来很奇怪这仍然是一个突出的问题。
你说得对 gmtime()
和 localtime()
函数不是线程安全的。 C 库中有不少这样的函数,它们之所以如此,是因为它们是为单线程程序设计的(曾经是唯一一种),将它们更改为依赖线程本地数据将是一种改动到他们先前定义的语义。它们不是 "totally broken" 因为许多程序只使用一个线程,并且因为只要小心使用它们也可以用于多线程程序。
话虽如此,这些是可重入版本已经标准化的众多功能之一(gmtime_r()
和 localtime_r()
);如果您可以使用可重入版本,那么它们是多线程程序的更好选择。