5

我正在将其他用户代码集成到我的中。他们有调用本地时间函数的库,该函数不是线程安全的。

我注意到一些奇怪的问题。如果他们的代码仅限于一个线程,localtime 仍然会导致问题吗?请注意,在我的代码的其他线程中,我调用 localtime_r (线程安全版本)。

谢谢。

4

1 回答 1

14

不是线程安全的原因localtime是它将结果 ( struct tm *) 存储在静态变量中。因此,只要您仅从单个线程调用此函数,就不会引起问题。

换句话说,localtime看起来像这样:

struct tm *localtime(time_t *timer)
{
   static struct tm tt;
   ... many lines that sets tt member variables ... 
   return &tt;
}

显然,如果两个线程调用这个函数,那么返回指针中的值将根据最后调用localtime()的线程和值timer是什么而“随机”改变。

该函数localtime_r是安全的,因为它接受 astruct tm *作为参数,并返回指向该变量的指针。而实际上,以上就是localtimeUSED是如何实现的。所以,如果代码localtime_r看起来有点像这样:

struct tm *localtime_r(time_t *timer, struct tm *result)
{
   ... many lines that sets result member variables ... 
   return result;
}

现在,当然,我们可以制作一个更短的版本localtime

struct tm *localtime(time_t *timer)
{
   static struct tm tt;
   return localtime_r(timer, &tt); 
}

Edit2: 的result参数对于localtime_r调用它的线程来说是唯一的,这当然是至关重要的。为这个参数设置一个static或全局变量将使它与以前的问题非常相似。

Edit3:当然还有另一种方法可以让它出错:

struct tm *a, *b;
... 
a = localtime(something);
... 
b = localtime(someother);

if (a->tm_sec != b->tm_sec) 
{
   ... this never happens ... 
}

在这种情况下,ab将指向完全相同的地方。如果使用相同的变量并且使用localtime_r不同的指针来接收数据并且期望指针指向不同的事物,则同样适用。

于 2013-05-15T21:15:24.603 回答