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;
}

编译 & 运行:

$ gcc -o main main.c
$ ./main
20180704225205
20180704225205

调用 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;
}

编译 & 运行:

$ gcc -o main main.c
$ ./main
20180704200531
20180704230531

C:时间函数 localtime localtime_r相关推荐

  1. linux c设置系统时间函数,Linux C 中获取local日期和时间 time()localtime()函数

    #include #define _DATETIME_SIZE 32 // GetDate - 获取当前系统日期 /** * 函数名称:GetDate * 功能描述:取当前系统日期 * * 输出参数: ...

  2. C语言学习笔记---时间函数asctime()和localtime()

      这两个时间函数原型如下: char *__cdecl asctime(const struct tm *_Tm);__CRT_INLINE struct tm *__cdecl localtime ...

  3. C语言时间函数(2)之time,ctime,gmtime,localtime,asctime,mktime

    一.时间相关说明 格林威治时间表示0时区的标准时间.其他时区的时间和此标准时间均有时间差.UTC(Universal Time Coordinated)是世界协调时间,是格林威治时间在互联网中的表示方 ...

  4. linux几种时间函数总结

    一.linux时间函数总结 最近的工作中用到的时间函数比较频繁,今天抽时间总结一下,在linux下,常用的获取时间的函数有如下几个:  asctime,  ctime, gmtime, localti ...

  5. C语言再学习 -- 时间函数

    在软件设计中经常会用到关于时间的处理,用来计算语句.函数的执行时间,这时就需要精确到毫秒甚至是微妙的时间.我们首先来介绍一下,时间单位: 时间单位还有:秒(s).毫秒(ms).微秒 (μs).纳秒(n ...

  6. Linux时间函数札记

    关于gmtime.gmtime_r.localtime.localtime_r 测试环境:vmware 7 + Redhat5.5,系统时间使用UTC,时区为上海. 1.函数功能介绍 使用man gm ...

  7. c语言时间函数状态,C语言的时间函数

    下面是C语言的获取本地时间和构造时间进行格式化时间显示输出的相关函数: This page is part of release 3.35 of the Linux man-pages project ...

  8. 时间基础概念及Linux中的时间函数

    时间基础概念及Linux中的时间函数 时间相关概念 GMT 时间 UTC 时间 时区 `Time Zone` 夏令时 `DST` 本地时间 `localtime` Linux 系统中的时间 时钟基础概 ...

  9. 日期与时间函数与夏令时的关系

    测试环境:VMware12 pro+CentOS 7 时间结构介绍: 1. time_t 为从公元1970 年1 月1 日0 时0 分0 秒算起至今的UTC 时间所经过的秒数 2. 结构tm的定义为 ...

最新文章

  1. 机器学习 凝聚态物理_机器学习遇到了凝聚的问题
  2. vux Cell组件
  3. GAE 随机获取实体
  4. System 中的数学函数
  5. 别再为找不到实用的HDRI素材而头疼了 看看这里
  6. matlab 图例自定义,matlab实现自定义曲线图以及图例
  7. java制作oa审批流程,传智播客JAVA培训OA项目 审批流转模块
  8. Mongo的基本shell操作(大全)
  9. 帆软FineBI试用
  10. 存储服务器和磁盘阵列有什么区别
  11. iOS视频通话问题总结及心路历程。。。
  12. 作业:从键盘输入10个浮点数,求其和及其平均值
  13. 周杰伦一发新歌,服务器为什就挂掉了?
  14. 《五》微信小程序中的 WXS(WeiXin Script)
  15. GIS与地质灾害评价
  16. Unity——螺旋运动
  17. linux c++编程教程,Linux下的C++编程入门教程.ppt
  18. 新手小白,用手机在家做情感短视频,一个视频赚了3000
  19. mipcms文章详情调用
  20. js获取手机型号和手机操作系统版本号

热门文章

  1. VC 最爱问的问题:你这个创业项目,如果腾讯跟进了,而且几乎是产品上完全复制,你会怎么办?
  2. Unity基础小案例---射击小球
  3. RIKIBOT使用系列-Jetson与树莓派系统镜像的烧写与备份
  4. Jetpack Compose 从入门到入门(四)
  5. 指派问题数学规划matlab,数学建模(一)线性规划
  6. promise setTimeout setInterval 执行顺序
  7. CDGA|盘点近年全国各部门、各城市颁布数字化转型的政策
  8. LINUX_常用命令讲解
  9. Expect 手册中文版_1
  10. 一套网页黑色主题的配色