现在的位置: 首页 > 综合 > 正文

关于时间函数localtime()返回值的注意问题

2012年09月01日 ⁄ 综合 ⁄ 共 1829字 ⁄ 字号 评论关闭

因为localtime()返回的是 static静态的变量,所以:静态变量在进行多线程编程时是危险的。

所以,我们要注意,如果涉及到多线程的编程,就必须要避免多个用户访问localtime()返回的变量的值的问题的时候,该static变量里面 的值总是发生改变。(因为我的项目中要求要设置新值进去,所以不能这样子,而是应该用个临时变量来保存localtime()的值,然后再在那个临时变量去设置和修改时间值,这样的话,你就能够防止多线程取值不一致的问题::有鬼)
,那么那个临时变量struct tm * tmp = new struct tm; 他的创建和销毁就需要靠你来 申请和释放了哦。
或者我们使用 localtime_r这个是可重入函数。
#include <cstdlib>
#include <iostream>
#include <time.h>
#include <stdio.h>

using namespace std;

int main(int argc, char *argv[])
{
    time_t tNow =time(NULL);
    time_t tEnd = tNow + 1800;
    //注意下面两行的区别
    struct tm* ptm = localtime(&tNow);
    struct tm* ptmEnd = localtime(&tEnd);

    char szTmp[50] = {0};
    strftime(szTmp,50,"%H:%M:%S",ptm);
    char szEnd[50] = {0};
    strftime(szEnd,50,"%H:%M:%S",ptmEnd);
    

    printf("%s /n",szTmp);
    printf("%s /n",szEnd);
    

    system("PAUSE");
    return EXIT_SUCCESS;
}

最后出来的结果是:

21:18:39

21:18:39

和最初想法不一致。

查阅localtime的文档,发现这段话:

This structure is statically allocated and shared by the functions gmtime and localtime. Each time either one of these functions is called the content of this structure is overwritten.

也就是说每次只能同时使用localtime()函数一次,要不就会被重写!

The localtime() function need not be reentrant. A function that is not required to be reentrant is not required to be thread-safe.

因此localtime()不是可重入的。同时libc里提供了一个可重入版的函数localtime_r();

Unlike localtime(), the reentrant version is not required to set tzname。

修改程序:

#include <cstdlib>
#include <iostream>
#include <time.h>
#include <stdio.h>

using namespace std;

int main(int argc, char *argv[])
{
    time_t tNow =time(NULL);
    time_t tEnd = tNow + 1800;

    //在这里修改程序
    //struct tm* ptm = localtime(&tNow);
    //struct tm* ptmEnd = localtime(&tEnd);
    struct tm ptm = { 0 };
    struct tm ptmEnd = { 0 };
    localtime_r(&tNow, &ptm);
    localtime_r(&tEnd, &ptmEnd);
    
    char szTmp[50] = {0};
    strftime(szTmp,50,"%H:%M:%S",&ptm);
    char szEnd[50] = {0};
    strftime(szEnd,50,"%H:%M:%S",&ptmEnd);
    printf("%s /n",szTmp);
    printf("%s /n",szEnd);

    system("PAUSE");
    return EXIT_SUCCESS;
}

最后出来的结果是:

10:29:06 
10:59:06

抱歉!评论已关闭.