localtime不是线程安全的,但是只能在一个线程中调用吗?

时间:2013-05-15 21:10:58

标签: c++ linux multithreading

我将其他用户代码集成到我的中。他们有一个调用localtime函数的库,它不是线程安全的。

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

感谢。

1 个答案:

答案 0 :(得分:10)

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是安全的,因为它以struct tm *作为参数,并返回指向该变量的指针。事实上,以上是localtime用于实施的方式。所以,如果localtime_r的代码看起来有点像这样:

struct tm *localtime(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的{​​{1}}参数对于调用它的线程是唯一的,这当然是至关重要的。为此参数设置localtime_r或全局变量将使其与以前的问题非常相似。

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

static

在这种情况下,struct tm *a, *b; ... a = localtime(something); ... b = localtime(someother); if (a->tm_sec != b->tm_sec) { ... this never happens ... } a将指向完全相同的位置。如果相同的变量用于b并且不同的指针用于接收数据并且期望指针指向不同的东西,则同样适用。