Linux C编程基础:获取时间
1.前言
对于linux下的编程,无论是用户态还是内核态,时间获取都是经常需要使用到的。以下分别从用户态和内核态整理了几个常用的时间获取接口,供编写代码时快速查阅。
2.用户态获取时间
- 2.1 clock_gettime()
#include <time.h>int clock_gettime (clockid_t __clock_id, struct timespec *__tp);
作用:根据系统时钟的类型,获取当前时间__clock_id:系统时钟的类型。常用取值:- CLOCK_REALTIME: 从1970年1月1日到目前的时间
- CLOCK_MONOTONIC: 系统启动时间
- CLOCK_PROCESS_CPUTIME_ID: 本进程运行时间
- CLOCK_THREAD_CPUTIME_ID: 本线程运行的时间
__tp: 存放当前的时间。返回值:成功则返回0,失败则返回-1
timespec结构体:
struct timespec
{__time_t tv_sec; /* Seconds. 秒 */__syscall_slong_t tv_nsec; /* Nanoseconds. 纳秒*/
};
示例:
#include <stdio.h>
#include <string.h>
#include <time.h>long long get_clock_sys_time_ns(void)
{struct timespec tp;long long time_ns = 0;clock_gettime(CLOCK_MONOTONIC, &tp);time_ns = (long long)tp.tv_sec * 1000000000 + tp.tv_nsec;return time_ns;
}int main(void)
{struct timespec tp;///< 获取从1970年1月1日到目前的时间memset(&tp, 0, sizeof(struct timespec));clock_gettime(CLOCK_REALTIME, &tp);printf("clock_id = CLOCK_REALTIME, sec = %ld, nsec = %ld\n", tp.tv_sec, tp.tv_nsec);///< 获取系统启动时间memset(&tp, 0, sizeof(struct timespec));clock_gettime(CLOCK_MONOTONIC, &tp);printf("clock_id = CLOCK_MONOTONIC, sec = %ld, nsec = %ld, sys_time = %lld ns\n", tp.tv_sec, tp.tv_nsec, get_clock_sys_time_ns());///< 获取本进程运行时间memset(&tp, 0, sizeof(struct timespec));clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);printf("clock_id = CLOCK_PROCESS_CPUTIME_ID, sec = %ld, nsec = %ld\n", tp.tv_sec, tp.tv_nsec);///< 获取本线程运行时间memset(&tp, 0, sizeof(struct timespec));clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp);printf("clock_id = CLOCK_THREAD_CPUTIME_ID, sec = %ld, nsec = %ld\n", tp.tv_sec, tp.tv_nsec);return 0;
}
- 2.2.gettimeofday()
#include <sys/time.h>int gettimeofday(struct timeval *tv, struct timezone *tz);
作用:获取当前时间(从1970年1月1日到目前的时间)tv:当前UTC时间tz:当前时区信息返回值:成功则返回0,失败则返回-1
timeval结构体:
struct timeval
{__time_t tv_sec; /* Seconds. 秒*/__suseconds_t tv_usec; /* Microseconds. 微秒*/
};
timezone结构体:
struct timezone{int tz_minuteswest; /* Minutes west of GMT. 和Greenwich时间差了多少分钟 */int tz_dsttime; /* Nonzero if DST is ever in effect. 日光节约时间的状态 */};
示例:
#include <stdio.h>
#include <string.h>
#include <sys/time.h>long long get_sys_time_ms(void)
{long long time_ms = 0;struct timeval tv;gettimeofday(&tv, NULL);time_ms = ((long long)tv.tv_sec*1000000 + tv.tv_usec) / 1000;return time_ms;
}int main(void)
{///< 获取系统时间printf("sys_time = %lld ms\n", get_sys_time_ms());return 0;
}
- 2.3.time()
#include <time.h>time_t time(time_t *tloc);
作用:获取1970-01-01 00:00:00 +0000至今的秒数(UTC)tloc:返回的秒存储指针返回值:成功则返回秒数,失败则返回-1,错误原因存在errno中。
time_t的类型:
typedef long time_t;
示例:
#include <stdio.h>
#include <time.h>time_t get_utc_time(void)
{return time(NULL);
}int main(int argc, char **argv)
{time_t utc_time = get_utc_time();printf("utc_time = %ld s\n", utc_time);return 0;
}
- 2.4.localtime()
#include <time.h>struct tm *localtime(const time_t *timep);
作用:将time_t类型的时间转换为struct tm类型的时间timep:当前UTC秒数返回值:返回当地时间
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] 夏玲时标识符*/
};
示例:
#include <stdio.h>
#include <time.h>time_t get_utc_time(void)
{return time(NULL);
}int main(int argc, char **argv)
{time_t utc_time = get_utc_time();printf("utc_time = %ld s\n", utc_time);struct tm *local_tm = localtime(&utc_time); printf("local time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", local_tm->tm_year + 1900,local_tm->tm_mon + 1,local_tm->tm_mday,local_tm->tm_hour,local_tm->tm_min,local_tm->tm_sec);return 0;
}
- 2.5.localtime_r()
#include <time.h>struct tm *localtime_r(const time_t *timep, struct tm *result);
作用:将time_t类型的时间转换为struct tm类型的时间timep:当前UTC秒数result:当地时间返回值:返回当地时间
注:
localtime不是一个线程安全的函数。对于实时性要求较高的系统,多个线程同时调用localtime,可能会造成数据被覆盖。使用localtime_r来替代。
示例:
#include <stdio.h>
#include <time.h>time_t get_utc_time(void)
{return time(NULL);
}int main(int argc, char **argv)
{time_t utc_time = get_utc_time();printf("utc_time = %ld s\n", utc_time);struct tm result;struct tm *local_tm = localtime_r(&utc_time, &result); printf("local time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", local_tm->tm_year + 1900,local_tm->tm_mon + 1,local_tm->tm_mday,local_tm->tm_hour,local_tm->tm_min,local_tm->tm_sec);printf("result time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", result.tm_year + 1900,result.tm_mon + 1,result.tm_mday,result.tm_hour,result.tm_min,result.tm_sec);return 0;
}
- 2.6.gmtime()
#include <time.h>struct tm *gmtime(const time_t *timep);
作用:返回tm结构的GMT时间(UTC时间)timep:当前UTC秒数返回值:返回当地时间
例子:
#include <stdio.h>
#include <time.h>time_t get_utc_time(void)
{return time(NULL);
}int main(int argc, char **argv)
{time_t utc_time = get_utc_time();printf("utc_time = %ld s\n", utc_time);struct tm *gmt_tm = gmtime(&utc_time); printf("gmt time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", gmt_tm->tm_year + 1900,gmt_tm->tm_mon + 1,gmt_tm->tm_mday,gmt_tm->tm_hour,gmt_tm->tm_min,gmt_tm->tm_sec);return 0;
}
localtime和gmtime的区别:
localtime和gmtime都是C语言中的函数,用于将time_t类型的时间转换为struct tm类型的时间。它们的区别在于,gmtime将time_t转换为UTC时间,即世界标准时间,而localtime将time_t转换为本地时间。
例子:使用gmtime与localtime接口返回的小时数来计算当地时区
#include <stdio.h>
#include <time.h>time_t get_utc_time(void)
{return time(NULL);
}int main(int argc, char **argv)
{time_t utc_time = get_utc_time();printf("utc_time = %ld s\n", utc_time);struct tm *gmt_tm = gmtime(&utc_time); printf("gmt time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", gmt_tm->tm_year + 1900,gmt_tm->tm_mon + 1,gmt_tm->tm_mday,gmt_tm->tm_hour,gmt_tm->tm_min,gmt_tm->tm_sec);int gmt_hour = gmt_tm->tm_hour;struct tm *local_tm = localtime(&utc_time); printf("local time = %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n", local_tm->tm_year + 1900,local_tm->tm_mon + 1,local_tm->tm_mday,local_tm->tm_hour,local_tm->tm_min,local_tm->tm_sec);int local_hour = local_tm->tm_hour;int local_time_zone = local_hour - gmt_hour;if (local_time_zone < -12) {local_time_zone += 24; } else if (local_time_zone > 12) {local_time_zone -= 24;}else{}printf("local_time_zone = %d\n", local_time_zone);return 0;
}
3.内核态获取时间
- 3.1.do_gettimeofday()(比较老的函数,新内核可能不存在了)
#include <linux/time.h> void do_gettimeofday(struct timeval *tv);
作用:与C标准库中gettimeofday()用法相同tv:当前UTC时间
timeval结构体:
struct timeval
{__time_t tv_sec; /* Seconds. 秒*/__suseconds_t tv_usec; /* Microseconds. 微秒*/
};
示例:
#include <linux/module.h>
#include<linux/time.h>
MODULE_LICENSE("GPL");int __init do_gettimeofday_init(void)
{printk("do_gettimeofday test begin.\n");struct timeval now={.tv_sec=0,.tv_usec=0}; //声明一个变量do_gettimeofday(&now); //调用函数获取时间,此时间是距离1970-01-01 00:00:00的时间/*显示当前时间差*/printk("the seconds of the day is: %ld\n", now.tv_sec); //秒数printk("the microseconds of the day is: %ld\n", now.tv_usec); //微秒数printk("do_gettimeofday test over.\n");return 0;
}void __exit do_gettimeofday_exit(void)
{printk("Goodbye do_gettimeofday test\n");
}module_init(do_gettimeofday_init);
module_exit(do_gettimeofday_exit);
-
3.2.基于ktime_t格式的时间
参考:linux kernel时钟获取 -
- ktime_get()
#include "linux/ktime.h"ktime_t ktime_get(void);作用:获取的是CLOCK_MONOTONIC时间。通过ktime_get获取的时间是不统计设备休眠时间的,并且这个时间统计的起始点则是设备启动后。
返回值:返回ktime_t格式的数据类型,单位为纳秒。ktime_t的定义:
typedef s64 ktime_t;示例:
time_test_drv_init ktime_t curTime = 0; curTime = ktime_get(); TIME_TEST_INFO("ktime_get:%lld ns", curTime); -
- ktime_get_ts64()
#include "linux/time64.h"void ktime_get_ts64(struct timespec64 *ts);作用:和ktime_get的功能是完全一样的,区别在于对时间的表示数据类型由ktime_t变成了timespec64。timespec64的定义如下:
struct timespec64 {time64_t tv_sec; /* seconds */long tv_nsec; /* nanoseconds */ };timespec64中包含了秒和纳秒,相对ktime_t纳秒这个时间表示更加适合人类查看.
示例:
static void show_time_ts64(const char* caller, const int line, const struct timespec64 *curTimeTs) {pr_info("%s,%d:%lld s %ld ns\n", caller, __LINE__, curTimeTs->tv_sec, curTimeTs->tv_nsec); }time_test_drv_init struct timespec64 curTimeTs; ktime_get_boottime_ts64(&curTimeTs); show_time_ts64(__func__, __LINE__, &curTimeTs); -
3.ktime_get_boottime()
static inline ktime_t ktime_get_boottime(void);作用:ktime_get_boottime获取的时间和ktime_get最大的不同是其包含了设备进入休眠的时间,其这个时间统计的起始点也是设备启动后。
返回值:返回值类型为ktime_t,单位为纳秒。示例:
time_test_drv_init ktime_t curTime = 0; curTime = ktime_get_boottime(); TIME_TEST_INFO("ktime_get_boottime:%lld ns", curTime); -
4.ktime_get_boottime_ts()
void ktime_get_boottime_ts64(struct timespec64 *);作用:ktime_get_boottime_ts相对于ktime_get_boottime的功能是完全一样的,区别在于对时间的表示数据类型由ktime_t变成了timespec64。 -
5.ktime_get_real()
ktime_t ktime_get_real(void);作用:ktime_get_real获取的时间的起点不是设备的启动时间点了,而是相对UTC的,即从1970开始。
示例:time_test_drv_init ktime_t curTime = 0; curTime = ktime_get_real(); TIME_TEST_INFO("ktime_get_real:%lld ns", curTime); -
6.ktime_get_real_ts()
void ktime_get_real_ts(struct timespec64 *);作用:ktime_get_real_ts相对于ktime_get_real的功能是完全一样的,区别在于对时间的表示数据类型由ktime_t变成了timespec64。
示例:time_test_drv_init struct timespec64 curTimeTs; ktime_get_real_ts64(&curTimeTs);
4.延时函数的实现
void delay_us(uint32_t nus)
{volatile uint32_t startts, endts, ts;ts = nus;startts = get_time_us();endts = startts + ts;if (endts > startts){while (get_time_us() < endts);}else{while (get_time_us() > endts);while (get_time_us() < endts);}
}
相关文章:
Linux C编程基础:获取时间
1.前言 对于linux下的编程,无论是用户态还是内核态,时间获取都是经常需要使用到的。以下分别从用户态和内核态整理了几个常用的时间获取接口,供编写代码时快速查阅。 2.用户态获取时间 2.1 clock_gettime() #include <time.h>int c…...
Spring核心注解
1、Bean注解 作用:用于把当前方法的返回值作为bean对象存入spring的ioc容器中位置: 一般出现在方法上面属性: name:用于指定bean的id。当不写时,默认值是当前方法的名称细节:当我们使用注解配置方法时,如果方法有参数,…...
哈希表原理,以及unordered_set/和unordered_map的封装和迭代器的实现
哈希表 unordered系列unordered_set和unordered_map的使用哈希哈希概念哈希冲突哈希函数闭散列开散列哈希表的扩容哈希表源码(开散列和闭散列) 封装unordered_set/和unordered_map,以及实现迭代器节点定义unordered_set定义unordered_map定义…...
如何把歌曲里的伴奏音乐提取出来,分享几个方法给大家!
对于一首歌,我们都知道,它有两部分组成:背景音乐人声。这两者合在一起,便是我们经常听的歌。部分用户想要直接获取歌曲伴奏,那么可以在UU伴奏网上下载。 操作方法比较简单,直接搜索想要的歌曲名称就可以了…...
区块链产业快速发展 和数集团开启区块链应用新时代
UTONMOS区块链游戏要来了。 就在5月底,UTONMOS品牌所属公司上海和数集团在泰国发布了【神念无界】系列的多款国际版链游,包括【神念无界-源起山海】、【北荒传奇】、【神宠岛】、【神农园】等区块链游戏。 以【神念无界-源起山海】为例,其是…...
初出茅庐的小李博客之常见字符串函数使用
C语言字符数组与字符串数组 在C语言中,字符数组和字符串数组实际上是同一种类型。字符串是由字符组成的字符数组,通常以空字符 ‘\0’ 结尾。C语言中的字符串是一种常见的数据类型。我们可以通过两种方式定义字符数组跟字符串数组 char charArray[10];…...
运筹学工程化流程和常见的运筹学算法分类以及常见软件
文章目录 前言运筹学工程化流程运筹学算法分类运筹学软件参考文献 前言 自2023年初新冠疫情管控放开后,各家公司各类岗位的人员都有被裁的消息传出,但用人市场上运筹学算法岗位却反其道行之,用工出现了激增。可以预见的是数据算法将从传统的…...
JAVA面向对象(三)
第三章 封装与继承 目录 第三章 封装与继承 1.1.封装 1.2.包 1.3.访问权限控制 1.4.static修饰符 1.4.1.成员变量 1.4.2.成员方法 1.4.3.代码块 总结 内容仅供学习交流,如有问题请留言或私信!!!!࿰…...
前端面试题---跨域处理和异常、错误处理
一.跨域处理 在前端开发中,当我们在浏览器中向不同域名或端口发起请求时,就会遇到跨域请求的限制。为了处理跨域请求,有几种常见的方法 1.JSONP(JSON with Padding) JSONP是一种利用 <script> 标签可以跨域加载…...
网络安全之反序列化漏洞分析
简介 FastJson 是 alibaba 的一款开源 JSON 解析库,可用于将 Java 对象转换为其 JSON 表示形式,也可以用于将 JSON 字符串转换为等效的 Java 对象分别通过toJSONString和parseObject/parse来实现序列化和反序列化。 使用 对于序列化的方法toJSONStrin…...
19 贝叶斯线性回归
文章目录 19 贝叶斯线性回归19.1 频率派线性回归19.2 Bayesian Method19.2.1 Inference问题19.2.2 Prediction问题 19 贝叶斯线性回归 19.1 频率派线性回归 数据与模型: 样本: { ( x i , y i ) } i 1 N , x i ∈ R p , y i ∈ R p {\lbrace (x_i, y_…...
第七十天学习记录:高等数学:微分(宋浩板书)
微分的定义 基本微分公式与法则 复合函数的微分 微分的几何意义 微分在近似计算中应用 sin(xy) sin(x)cos(y) cos(x)sin(y)可以用三角形的几何图形来进行证明。 假设在一个单位圆上,点A(x,y)的坐标为(x,y),点B(x’, y’)的坐标为(x’, y’)。则以两点…...
Jmeter
目录 一、jmeter 安装 二、jmeter 介绍 1、jmeter是什么? 2、jmeter 用来做什么? 3、优点 4、缺点 5、jmeter 目录介绍 ①_bin 目录介绍 ② docs 目录 — — 接口文档目录 ③ extras目录 — — 扩展插件目录 ④ lib 目录 — — 所用到的插件目录 ⑤ lic…...
Flutter 学习 之 时间转换工具类
Flutter 学习之时间转换工具类 在 Flutter 应用程序开发中,处理时间戳是非常常见的需求。我们通常需要将时间戳转换为人类可读的日期时间格式。为了实现这一点,我们可以创建一个时间转换工具类。 实现方法 以下是一个简单的时间转换工具类的示例&…...
docker consul
docker consul的容器服务更新与发现 服务注册与发现是微服务架构中不可或缺的重要组件,起始服务都是单节点的,不保障高可用性,也不考虑服务的承载压力,服务之间调用单纯的通过接口访问的,直到后来出现多个节点的分布式…...
全志V3S嵌入式驱动开发(开发环境再升级)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们陆陆续续开发了差不多有10个驱动,涉及到网口、串口、音频和视频等几个方面。但是整个开发的效率还是比较低的。每次开发调试的…...
ChatGPT:人工智能助手的新时代
ChatGPT:人工智能助手的新时代 文章目录 ChatGPT:人工智能助手的新时代引言ChatGPT的原理GPT-3.5架构概述预训练和微调过程生成式对话生成技术 ChatGPT的应用场景智能助理客服机器人虚拟角色教育辅助创意生成个性化推荐 ChatGPT的优势ChatGPT的使用技巧与…...
【面试】二、Java补充知识
JVM中的存储 JVM的五块存储区: 方法区(线程共享) 方法区用来存储类的各种信息(类名、方法信息等)、静态变量、常量和编译后的代码也存储在方法区中 方法区中也存在运行时常量池 常量池中会存放程序运行时生成的各种…...
LISTENER、TNSNAMES和SQLNET配置文件
LISTENER、TNSNAMES和SQLNET配置文件 用户连接验证listener.ora文件配置监听日志local_listener参数 tnsnames.ora文件配置 sqlnet.ora文件配置 用户连接验证 Oracle数据库中用户有三种常见的登录验证方式: 通过操作系统用户验证:必须是在数据库服务器…...
【Leetcode -225.用队列实现栈 -232.用栈实现队列】
Leetcode Leetcode -225.用队列实现栈Leetcode -232.用栈实现队列 Leetcode -225.用队列实现栈 题目:仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 …...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
