【发布时间】:2016-09-09 13:11:20
【问题描述】:
我正在研究 C 时间库的例程,因为我需要一种方法来跟踪程序日志文件中的时间。我发现做到这一点的方法是拥有一个time_t 对象,它仅包含自 1970 年 1 月 1 日 00:00 UTC 以来的秒数。然后,我将这个time_t 对象解析为localtime(time_t* argument) 例程,这将返回一个指向tm 结构的指针。后者将把时间保存在一个更复杂的结构中,从 1970 年 1 月 1 日起,以秒为单位转换年、月、日、小时等的时间。tm 结构指针最终可以被asctime(strcut tm* argument) 用来返回日志的人类友好时间(即 2016 年 9 月 7 日星期三 13:45:23)。
我的问题是关于 struct tm 对象。正如我们在Cplusplus 的示例代码中看到的那样,从未声明过struct tm 对象,只有一个指针。这意味着该对象在其他地方声明,我们只是在访问它。参考链接本身指出:
"The function also accesses and modifies a shared internal object,
which may introduce data races on concurrent calls to gmtime and
localtime. Some libraries provide an alternative function that avoids
this data race: localtime_r (non-portable)."
那么,谁创建了struct tm 对象?是第一次加载的C时间库吗?这意味着加载库的第一个进程将声明该对象,而所有其他进程将只与已声明的对象共享该库?为了避免那些数据竞争问题,为每个调用创建一个新的struct tm 对象并返回一个指向它的指针,这样每个程序都有自己的结构不是更好吗?
也许每个使用 Ctime 的程序都有一个 struct tm MyProgramStruct; localtime(&Rawtime, &MyProgramStruct); 而不是一个结构?有什么理由这样做吗?
最后,使用 C 时间库 localtime 例程是不是一种不好的做法,因为程序不同步可能导致错误输出?
链接中的示例代码:
/* localtime example */
#include <stdio.h> /* puts, printf */
#include <time.h> /* time_t, struct tm, time, localtime */
int main ()
{
time_t rawtime;
struct tm * timeinfo;
time (&rawtime);
timeinfo = localtime (&rawtime);
printf ("Current local time and date: %s", asctime(timeinfo));
return 0;
}
【问题讨论】:
-
当然,那是个坏主意。不是唯一的,考虑 errno、strtok、setlocale、gmtime、fcvt。每个 CRT 实现都需要解决这个令人头疼的问题,它们的做法都不同。要是那时他们有时光机就好了……
标签: c time shared-libraries