协调时间时(Coordinated Universal Time),又称国际标准时间、世界统一时间等,英文可缩写为CUT、UTC、TUC等。
即,格林威治时间。同UTC时间。
【注】:localtime、gmtime和ctime返回的是同一个静态对象区,该静态区会被下一次调用覆盖。
trace打印时间代码片段如下,
实际上两处陷阱导致的上述现象:
所以,localtime()、gmtime()和ctime()三个函数不能多线程并行调用,否则会相互干扰。
而gbase中的确还有其它线程在使用gmtime,例如以下代码片段(不仅限这一处),
先将本地时区设置为+8区(Asia/Shanghai)。编写一个多线程小程序,代码片段如下,
// 线程0执行以下代码: time_t curtime = time(NULL); struct tm* cdt = localtime(&curtime); char strtime[25] = ""; sprintf(strtime, "%02d:%02d:%02d", cdt->tm_hour, cdt->tm_min, cdt->sec); printf("thread [0] time is %s\n", strtime); // 线程1执行以下代码: time_t curtime = time(NULL); struct tm* cdt = gmtime(&curtime); char strtime[25] = ""; sprintf(strtime, "%02d:%02d:%02d", cdt->tm_hour, cdt->tm_min, cdt->sec);
这里我们只打印线程0输出,线程1起干扰作用。运行此程序(当前系统时间是09:12),可以观察到相同现象,下图所示,
将非线程安全的函数替换成线程安全的版本,例如,localtimer代替localtime,gmtimer代替gmtime、ctime_r代替ctime。
【注】:这三个线程安全函数内部有锁。
gbase的原型IB,使用了不仅限以上所述的非线程安全函数,随着更多代码被多线程化,以及第三方库的引入,其中的隐患也在增加,原本不是问题的小地方也会成为问题。后续,我们将调用此类问题。