在写代码的时候,经常会用到读取系统时间的函数。很多人都会调用localtime函数来将时间转换本地时间,但是大家往往会忽略了一点,localtime函数不是线程安全的。如果在多线程里调用localtime函数,很可能会出现问题。

struct tm *localtime(const time_t *clock);

这个函数在返回的时候,返回的是一个指针,实际的内存是localtime内部通过static申请的静态内存,所以通过localtime调用后的返回值不及时使用的话,很有可能被其他线程localtime调用所覆盖掉

多线程应用里面,应该用localtime_r函数替代localtime函数,因为localtime_r是线程安全的。

struct tm* localtime_r( const time_t* timer, struct tm* result );

转载二:

上程序:

[c-sharp] view plaincopy
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <time.h>
  4. #include <stdio.h>
  5. using namespace std;
  6. int main(int argc, char *argv[])
  7. {
  8. time_t tNow =time(NULL);
  9. time_t tEnd = tNow + 1800;
  10. //注意下面两行的区别
  11. struct tm* ptm = localtime(&tNow);
  12. struct tm* ptmEnd = localtime(&tEnd);
  13. char szTmp[50] = {0};
  14. strftime(szTmp,50,"%H:%M:%S",ptm);
  15. char szEnd[50] = {0};
  16. strftime(szEnd,50,"%H:%M:%S",ptmEnd);
  17. printf("%s /n",szTmp);
  18. printf("%s /n",szEnd);
  19. system("PAUSE");
  20. return EXIT_SUCCESS;
  21. }

最后出来的结果是:

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。

修改程序:

[c-sharp] view plaincopy
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <time.h>
  4. #include <stdio.h>
  5. using namespace std;
  6. int main(int argc, char *argv[])
  7. {
  8. time_t tNow =time(NULL);
  9. time_t tEnd = tNow + 1800;
  10. //在这里修改程序
  11. //struct tm* ptm = localtime(&tNow);
  12. //struct tm* ptmEnd = localtime(&tEnd);
  13. struct tm ptm = { 0 };
  14. struct tm ptmEnd = { 0 };
  15. localtime_r(&tNow, &ptm);
  16. localtime_r(&tEnd, &ptmEnd);
  17. char szTmp[50] = {0};
  18. strftime(szTmp,50,"%H:%M:%S",&ptm);
  19. char szEnd[50] = {0};
  20. strftime(szEnd,50,"%H:%M:%S",&ptmEnd);
  21. printf("%s /n",szTmp);
  22. printf("%s /n",szEnd);
  23. system("PAUSE");
  24. return EXIT_SUCCESS;
  25. }

最后出来的结果是:

10:29:06 
10:59:06

localtime与localtime_r相关推荐

  1. localtime和localtime_r

    C:时间函数 localtime localtime_r localtime 和 localtime_r 的函数功能: converts the calendar time timep to brok ...

  2. localtime 和 localtime_r

    上程序: #include <cstdlib> #include <iostream> #include <time.h> #include <stdio.h ...

  3. 二十 关于gmtime、gmtime_r、localtime、localtime_r

    测试环境:vmware 7 + Redhat5.5,系统时间使用UTC,时区为上海. 1.函数功能介绍 使用man gmtime或man localtime都可以的得到这几个函数的介绍.原型如下: s ...

  4. Linux下gmtime、gmtime_r、localtime、localtime_r函数详解

    函数功能介绍 使用man gmtime或man localtime都可以的得到这几个函数的介绍.原型如下: struct tm *gmtime(const time_t *timep); struct ...

  5. Linux时间函数time()、ctime()、ctime_r()、localtime()、localtime_r()、asctime()、strftime()的转换关系

    上面这个图就是它们所有函数的关系转换,比较清晰,不需要太多文字描述. 下面是它们的代码实现过程: #include<stdio.h> #include<unistd.h> #i ...

  6. Linux gmtime、gmtime_r、localtime、localtime_r介绍

    测试环境:vmware 7 + Redhat5.5,系统时间使用UTC,时区为上海. 1.函数功能介绍 使用man gmtime或man localtime都可以的得到这几个函数的介绍.原型如下: s ...

  7. localtime、localtime_s、localtime_r的使用

    (1).localtime用来获取系统时间,精度为秒 #include <stdio.h> #include <time.h>int main() {time_t time_s ...

  8. C:时间函数 localtime localtime_r

    C:时间函数 localtime localtime_r localtime 和 localtime_r 的函数功能: converts the calendar time timep to brok ...

  9. localtime死锁——多线程下fork子进程

    最近测试我们自己改进的redis,发现在做rdb时,子进程会一直hang住,gdb attach上,堆栈如下: (gdb) bt #0 0x0000003f6d4f805e in __lll_lock ...

最新文章

  1. Python学习笔记17:标准库之数学相关(math包,random包)
  2. 【OpenCV】图像代数运算:平均值去噪,减去背景
  3. 概率图论PGM的D-Separation(D分离)
  4. MongoDB【快速入门】
  5. 重识微信:花 8 小时列举微信功能
  6. 4k视频写入速度要求_为什么视频工作者需要外置硬盘?
  7. 计算机学生工学交替报告书,工学交替学生守则
  8. pdo 错误 php,多语句查询中的PHP PDO错误
  9. 第一章--电商设计表电商项目--数据库设计
  10. 嵌入网站的挖矿代码——Monerominer.rocks
  11. apache 设置404 页面_Apache和Nginx解析漏洞
  12. cropper.js 裁剪图片并上传(文档翻译+demo)
  13. quartz 数据库表含义解释
  14. Proxmox VE 7.2 更改登录横幅
  15. wd移动硬盘不能识别_西数移动硬盘电脑提示无法识别USB设备怎么办
  16. 颜色的前世今生19·外传之PPI、LPI、DPI疑难问题解答
  17. 到底什么是类脑计算?
  18. 虚拟机安装Linux系列教材 (二)- 关闭Hiper-V
  19. 太极链在协商共识协议中发挥的作用
  20. Java的激荡发展史。一部激情昂扬的血泪史。技术的发展离不开商业的追逐,商业利益的追逐诞生更多的技术

热门文章

  1. fodera开机启动优化
  2. PostgreSQL在何处处理 sql查询
  3. postfix+squirrelmail - rhat 5.4
  4. CodeForces - 1529F It‘s a bird! No, it‘s a plane! No, it‘s AaParsa!(最短路+思维建图)
  5. ZOJ - 4122 Triangle City(最短路+欧拉通路+思维)
  6. python基础语法-异常处理
  7. 像加载DLL一样加载EXE
  8. BOOST内存管理(二) --- boost::pool
  9. C语言struct中冒号用法
  10. 对现有的所能找到的DDOS代码(攻击模块)做出一次分析----自定义攻击篇