Linux时间相关知识小结:struct timeval、timespec、gettimeofday、time、localtime....
前言
我们在linux平台进行开发时,时间相关的操作基本上都会遇到,本文就对常用的时间相关的结构体、接口进行分析小结。
常见类型、结构体定义
timespec
原型
struct timespec
{__time_t tv_sec; /* Seconds. 秒 */__syscall_slong_t tv_nsec; /* Nanoseconds. 纳秒*/
};
说明
该结构体只是包括秒和纳秒,并没有任何其他含义,比如1970年以来的秒数等。只是个存放空间。为clock_gettime的出参。
clock_gettime
原型
int clock_gettime (clockid_t __clock_id, struct timespec *__tp);
说明
根据clock_id(系统时钟)的类型,获取当前时间。
参数说明
clock_id常用取值枚举说明
枚举值 | 说明 |
---|---|
CLOCK_REALTIME | 系统当前时间,从1970年1月1日算起 |
CLOCK_MONOTONIC | 从系统启动时间算起,经过的时间 |
CLOCK_PROCESS_CPUTIME_ID | 本进程运行时间 |
CLOCK_THREAD_CPUTIME_ID | 本线程运行的时间 |
程序示例
#include <time.h>
#include <stdio.h>
#include <sys/time.h>int main(void)
{struct timespec tsp;printf("CLOCK REALTIME time:\n");clock_gettime(CLOCK_REALTIME, &tsp);printf("sec:%ld, nsec:%ld\n", tsp.tv_sec, tsp.tv_nsec);printf("-----------------------\n");printf("CLOCK MONOTONIC time:\n");clock_gettime(CLOCK_MONOTONIC, &tsp);printf("sec:%ld, nsec:%ld\n", tsp.tv_sec, tsp.tv_nsec);printf("-----------------------\n");printf("CLOCK PROCESS CPUTIME ID time:\n");clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tsp);printf("sec:%ld, nsec:%ld\n", tsp.tv_sec, tsp.tv_nsec);printf("-----------------------\n");printf("CLOCK THREAD CPUTIME ID time:\n");clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tsp);printf("sec:%ld, nsec:%ld\n", tsp.tv_sec, tsp.tv_nsec);printf("-----------------------\n");return 0;
}
运行结果:
CLOCK REALTIME time:
sec:1644155596, nsec:748701786
-----------------------
CLOCK MONOTONIC time:
sec:12526311, nsec:817330221
-----------------------
CLOCK PROCESS CPUTIME ID time:
sec:0, nsec:585929
-----------------------
CLOCK THREAD CPUTIME ID time:
sec:0, nsec:590570
timeval
原型
struct timeval
{__time_t tv_sec; /* Seconds. 秒*/__suseconds_t tv_usec; /* Microseconds. 微秒*/
};
说明
该结构体只是包括秒和微秒,并没有任何其他含义,比如1970年以来的秒数等。只是个存放空间。为gettimeofday的出参。
timezone
原型
struct timezone{int tz_minuteswest; /* Minutes west of GMT. 和Greenwich时间差了多少分钟 */int tz_dsttime; /* Nonzero if DST is ever in effect. 日光节约时间的状态 */};
说明
该结构体为时区相关信息,用的比较少,gettimeofday的出参。一般我们也可以直接传入NULL.
gettimeofday
原型
int gettimeofday(struct timeval *tv, struct timezone *tz);
说明
获取当前时间,为UTC时间,1970年以来的秒+微秒、时区信息。
参数说明
参数 | 类型 | 说明 |
---|---|---|
tv | struct timeval * | 出参,当前UTC时间 |
tz | struct timezone * | 当前时区信息 |
返回值
成功则返回0,失败则返回-1,错误原因存在errno中。
程序示例
#include <time.h>
#include <stdio.h>
#include <sys/time.h>int main(void)
{struct timeval tv;struct timezone tz;printf("gettimeofday time:\n");gettimeofday(&tv, &tz);printf("tv_sec:%ld tv_usec:%ld\n", tv.tv_sec, tv.tv_usec);printf("tz:%d %d\n", tz.tz_dsttime, tz.tz_minuteswest);return 0;
}
运行结果:
gettimeofday time:
tv_sec:1644156383 tv_usec:513679
tz:0 0
time_t
原型
typedef long time_t;
说明
该类型其实就是long int ,用于存储秒数,是time函数的入参和返回值。
time
原型
time_t time(time_t *t)
说明
该函数会返回从1970年1月1日0时0秒算起到现在所经过的秒数,如果t为非空指针的话,该函数还会将返回值存储到t指针所指的内存里。
参数说明
参数 | 类型 | 说明 |
---|---|---|
t | time_t * | 返回的秒存储指针 |
返回值
成功则返回秒数,失败则返回-1,错误原因存在errno中。
程序示例
#include <time.h>
#include <stdio.h>
#include <sys/time.h>int main(void)
{time_t timep1, timep2;timep1 = time(NULL);time(&timep2);printf("timep1:%ld timep2:%ld\n", timep1, timep2);return 0;
}
运行结果:
timep1:1644157011 timep2:1644157011
tm
原型
struct tm
{int tm_sec; /* Seconds. [0-60] (1 leap second) */int tm_min; /* Minutes. [0-59] */int tm_hour; /* Hours. [0-23] */int tm_mday; /* Day. [1-31] */int tm_mon; /* Month. [0-11] 注意:0代表1月,以此类推*/int tm_year; /* Year - 1900. 该值为实际年份减去1900*/int tm_wday; /* Day of week. [0-6] 注意:0代表星期一,以此类推*/int tm_yday; /* Days in year.[0-365] 从每年的1月1日开始的天数,其中0代表1月1日,以此类推*/int tm_isdst; /* DST. [-1/0/1] 夏玲时标识符*/
};
说明
该类型用于描述真实世界所使用的时间日期,包括年月日时分秒周等, 是localtime的返回值
localtime
原型
struct tm *localtime(const time_t *timep);
说明
将参数timep所指的当前秒数转换成真实世界所使用的时间日期表示方法,结果返回。
参数说明
参数 | 类型 | 说明 |
---|---|---|
timep | time_t | 当前UTC秒数 |
返回值
当前UTC秒数对应的年月日时分秒周等。
程序示例
#include <time.h>
#include <stdio.h>
#include <sys/time.h>int main(void)
{time_t timep;struct tm *p;timep = time(NULL);printf("timep:%ld\n", timep);p = localtime(&timep);// 对年、月要进行相应的处理printf("%d-%d-%d %d:%d:%d \n", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);return 0;
}
运行结果:
timep:1644157741
2022-2-6 22:29:1
localtime_r
在上面localtime的程序示例中,可以发现,localtime的返回值是 struct tm *类型,也就是指向struct tm类型的指针,这样使用并不会造成内存泄露等问题,这是因为localtime的返回值其实指向了一个静态变量,这是静态库已经定义的static struct tm类型数据,很明显,由于程序使用静态变量,会导致localtime不可重入,也就是非现成安全,对于一般的应用场景并不会带来什么隐患,但是对于实时性要求高的场所,会带来问题,因为多次调用localtime会造成返回值覆盖。
比如:
两个线程A和B同时调用 localtime 函数:
时刻1:线程A调用 localtime 函数,得到一个指针,tm中存储的值更新为 value-A
时刻2:线程B调用 localtime 函数,得到一个指针, tm中存储的值更新为 value-B
时刻3:线程A对 localtime 返回的指针进行相关引用操作(例如 printf 输出某字段),此时 static struct tm 中的值实际是 value-b,并非预期的 value-a
时刻4:线程B对 localtime 返回的指针进行相关引用操作,此时 static struct tm 中的值实际是 value-b
所以为了解决localtime不可重入的问题,就出现了localtime_r。
原型
struct tm *localtime_r(const time_t *timep, struct tm *result);
说明
调用 localtime 只需要传入指向 time_t 的一个常量指针;
调用 localtime_t 不仅需要传入指向 time_t 的一个常量指针,还需要传入指向 struct tm 的一个指针,结果将存储在 result 指向的 struct tm 对象中;
程序示例
#include <time.h>
#include <stdio.h>
#include <sys/time.h>int main(void)
{time_t timep;struct tm *p;struct tm res;timep = time(NULL);printf("timep:%ld\n", timep);localtime_r(&timep, &res);printf("%d-%d-%d %d:%d:%d \n", 1900 + res.tm_year, 1 + res.tm_mon, res.tm_mday, res.tm_hour, res.tm_min, res.tm_sec);return 0;
}
运行结果:
timep:1644158806
2022-2-6 22:46:46
小结
以上为linux平台下,与时间相关的常用结构体、变量、接口定义,再详细的说明可以参考相关源码定义。
Linux时间相关知识小结:struct timeval、timespec、gettimeofday、time、localtime....相关推荐
- struct timeval结构体 以及 gettimeofday()函数、struct timespec结构体
struct timeval结构体 struct timeval结构体在time.h中的定义为: struct timeval { __time_t tv_sec; /* Seconds. */ __ ...
- Linux高精度struct timespec和struct timeval
1. 结构基本定义 1.1 struct timespec 定义 typedef long time_t; #ifndef _TIMESPEC #define _TIMESPEC struct tim ...
- Linux高精度struct timespec 和 struct timeval
struct timespec now_ts;clock_gettime(CLOCK_MONOTONIC, &now_ts);printf("os tick times, %ld s ...
- struct timespec 和 struct timeval
struct timespec 和 struct timeval time()提供了秒级的精确度 . 1.头文件 <time.h> 2.函数原型 time_t time(time_t * ...
- struct timeval的处理(timeval比较及相减)
timeval结构体的处理函数 timeval的大小比较 timeval转为double类型的秒 两个timeval类型之间的时间差 函数耗时测试 timeval的大小比较 /************ ...
- struct timeval 和 struct timespec 应用小结
在基于linux的C编程中,经常会看到 struct timeval和struct timespec 这两个跟时间有关的结构体,有时候会容易混淆,先看下这两个结构体的定义,以linux-2.6.35为 ...
- linux系统中struct timeval结构体、struct timezone结构体以及gettimeofday函数
格林尼治时间.协调世界时 间.世界时间.日光节约时间以及时区等介绍: 格林尼治时间(Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台当地的标准时间,因为本初子午 ...
- Linux tm time_t timeval timespec以及与时间相关函数用法
一.时间类型 linux中编程通常需要用到时间变量,和相关的时间操作函数.常用的时间类型有: time_t .struct timeval.struct timespec.struct tm ...
- linux下的ktime_t timeval timespec
内核中,经常看到ktime_t变量,总结下 ktime_t Nanosecond//纳秒 /* Nanosecond scalar representation for kernel time val ...
最新文章
- 使用python愉快地做高数线代题目~
- 用Python防止头上一片青青草原
- Github上十大热门可视化面板!再也不用担心画图啦!
- .NET3.5中的高性能 Socket API
- Ubuntu上面安装Redis Python
- angular 动画_如何在Angular 6中使用动画
- 19.Delete Documents-官方文档摘录
- PostgreSQL 10 自定义并行计算聚合函数的原理与实践
- 开菜鸟驿站需要什么条件?投入成本大概要多少?
- 二下语文书电子课本_沪教版牛津英语小学五年级上册高清电子课本教材书(三年级起点)...
- ValueError: This model has not yet been built. Build the model first by calling `build()` or calling
- 一篇文章教你用matlab求定积分广义/变限积分
- mac 编译mysql 源码_Mac上编译MySQL源码与安装
- 怎样绘制流程图?分享拼多多购物流程图模板及绘制技巧
- Android一键加群实现
- OJ一元二次方程的根*易错点
- Audio Hijack for Mac(音频录制工具)
- IMDB算法(贝叶斯算法)
- 从中国的山水画谈谈游戏场景设计该有的状态
- 用新华字典来彻底解释清:数据库索引到底是什么
热门文章
- 鱼群算法在上网行为管理系统中可以起到怎样的作用
- Python爬虫突破封禁的6种常见方法
- [RK3399][Android7.1.1]Android->输入法:设置默认输入法及输入法相关设置
- Php / Thinkphp 之 使用phpqrcode 生成自定义二维码
- php opcache 作者,PHP Opcache配置
- 复星旅文拟12月中旬上市:最高募资42亿港元 淘宝做基石投资
- Mosh Python 学习笔记
- postman在线测试webservice调用
- C#打开docx文件 (其他文件类似)
- Java 泛型中的通配符详解