C:时间函数 localtime localtime_r
localtime 和 localtime_r 的函数功能: converts the calendar time timep to broken-time representation

在调用 localtime 和 localtime_t 函数时,需特别注意:

localtime 是不可重入函数,非线程安全

localtime_r 是可重入函数,线程安全

使用 localtime 时不可重入示范:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>int main()
{time_t curTime = time(NULL);time_t aftTime = curTime + 3600*3;struct tm *pTm1 = localtime(&curTime);struct tm *pTm2 = localtime(&aftTime);fprintf(stdout, "%04d%02d%02d%02d%02d%02d\n",pTm1->tm_year + 1900,pTm1->tm_mon + 1,pTm1->tm_mday,pTm1->tm_hour,pTm1->tm_min,pTm1->tm_sec);fprintf(stdout, "%04d%02d%02d%02d%02d%02d\n",pTm2->tm_year + 1900,pTm2->tm_mon + 1,pTm2->tm_mday,pTm2->tm_hour,pTm2->tm_min,pTm2->tm_sec);return 0;
}

执行结果:

ann@ubuntu#:~/ann/localtime$ ./a.out
20220712195837
20220712195837

调用 localtime 函数并获取其返回值(一个指向 struct tm 结构类型数据的指针)后,我们并未对返回值进行显式地释放。

这并没有什么问题(不会导致内存泄漏)。

因为 localtime 函数返回值是一个指针,指向一个静态变量,这个静态变量是库中的一个 static struct tm 类型数据。

man localtime:

The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions.

这将引出新的问题,同一进程多个线程中同时调用(极短时间内连续调用) localtime 函数,返回值(tm)可能被覆盖。

举个栗子:

两个线程A和B同时调用 localtime 函数:
时刻1:线程A调用 localtime 函数,得到一个指针,指向 static struct tm 类型变量;(tm中存储的值更新为 value-a)
时刻2:线程B调用 localtime 函数,得到一个指针,指向 static struct tm 类型变量;(tm中存储的值更新为 value-b)
时刻3:线程A对 localtime 返回的指针进行相关引用操作(例如 printf 输出某字段),此时 static struct tm 中的值实际是 value-b,并非预期的 value-a
时刻4:线程B对 localtime 返回的指针进行相关引用操作,此时 static struct tm 中的值实际是 value-b

上面的示范代码虽然是在同一线程中,但是已经可以简单模拟这样的多线程执行调用流程。

如何解决?

localtime_r 是 localtime 的可重入版本(线程安全版本)。

localtime 不可重入是由于 static struct tm 是库中的一个静态变量,如果我们在调用 localtime 时传入一个 struct tm 类型变量(指针)用于存放结果,岂不是实现可重入?

Bingo!

struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);

调用 localtime 只需要传入指向 time_t 的一个常量指针;

调用 localtime_t 不仅需要传入指向 time_t 的一个常量指针,还需要传入指向 struct tm 的一个指针,结果将存储在 result 指向的 struct tm 对象中;

The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions.

The localtime_r() function does the same, but stores the data in a user-supplied struct.

使用 localtime_r 时可重入示范:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>int main()
{time_t curTime = time(NULL);time_t aftTime = curTime + 3600*3;struct tm tm1;struct tm tm2;localtime_r(&curTime, &tm1);localtime_r(&aftTime, &tm2);fprintf(stdout, "%04d%02d%02d%02d%02d%02d\n",tm1.tm_year + 1900,tm1.tm_mon + 1,tm1.tm_mday,tm1.tm_hour,tm1.tm_min,tm1.tm_sec);fprintf(stdout, "%04d%02d%02d%02d%02d%02d\n",tm2.tm_year + 1900,tm2.tm_mon + 1,tm2.tm_mday,tm2.tm_hour,tm2.tm_min,tm2.tm_sec);return 0;
}

执行结果:

ann@ubuntu#:~/ann/localtime$ ./a.out
20220712170110
20220712200110

————————————————
版权声明:本文为CSDN博主「test1280」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/test1280/article/details/80917962

localtime和localtime_r相关推荐

  1. localtime与localtime_r

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

  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. 使用Tensor Expression张量表达式处理算子
  2. thymeleaf加载不了js引用_web前端教程之js中的模块化一
  3. 重温一遍数据结构之单链表(golang版)
  4. Java设计模式(十五):桥接设计模式
  5. python的for循环累加_在python中将6 for循环累计和矢量化
  6. LeetCode 287. Find the Duplicate Number
  7. php-5.6.31安装视频教程_php安装图解教程
  8. html 放到底部,html – 将元素放在页面底部
  9. itextpdf paragraph使用
  10. 阿里巴巴android开发规范,阿里巴巴开发手册|阿里巴巴Android开发手册 PDF电子版_最火软件站...
  11. COSMOS认证咨询,Cosmo-天然产品标准以及Cosmo有机产品标准分为哪几大类
  12. oracle 表字段拆分,oracle 字段拆分
  13. 周志华《机器学习》习题1.2
  14. 内外兼修 A.O.史密斯燃气热水器新品开创新“静”界
  15. 记一次解决500错误
  16. TortoiseSVN控制台提交命令
  17. php表单生成Excel,PHPExcel多表单数据导出
  18. Word中的公式显示不全,或许是这个原因
  19. 史上最全的 Java 技术体系思维导图
  20. python制作圣诞贺卡_个性化的圣诞贺卡

热门文章

  1. small rtos51学习资料收集
  2. Latex 引号输入
  3. oracle blob 照片,要在oracle里面存入图片 用 blob类型
  4. 黑苹果详细安装教程-基于OpenCore官网指导-UPUPMO(macOS Monterey)
  5. HorizontalScrollView的基本使用,适合初学者
  6. STM8S---IO复用配置(STVP方式)
  7. UpdateData() 函数
  8. 机器学习——线性回归(拟合一条直线)
  9. 用talib列举某股票历史数据中2只乌鸦形态出现时间
  10. Matlab学习日记(2)输入与输出