linux时间函数
‘壹’ linux时间的获取与使用
Linux系统中的时间包含两种形式,日历时间和进程时间。日历时间表示从1970年1月1日0点(UTC时间)以来的秒数累计值,通过time_t数据类型保存,最后转换得到我们熟悉的24小时或12小时制时间。而进程时间,即CPU时间,衡量进程使用中央处理器资源的量,以时钟滴答计算。
获取日历时间的函数time()返回时间戳,为从1970年1月1日0点到现在经历的秒数,如返回值1533287924。为了获得更高精度的时间,使用gettimeofday()和clock_gettime()函数。gettimeofday()函数用timeval结构体保存微秒精度的时间戳,clock_gettime()函数用timespec结构体保存纳秒精度的时间戳。
将时间戳转化为日/月/年的时间,使用tm结构体。通过gmtime()和localtime()函数将time_t类型的时间戳转换为tm结构体表示的日期时间。固定格式打印时间,可以使用ctime()和asctime()函数,但这两个函数已被标记为弃用。更安全的方法是采用strftime()函数,它支持自定义格式化输出日期和时间。
在业务程序中,对比时间的先后通常通过时间戳进行,mktime()函数用于将struct tm结构体转换为time_t的时间戳,便于比较和计算。但在转换时需要注意,使用localtime()函数得到的时间戳是从1900年1月1日开始计算的,可能需要调整以得到准确结果。
Linux系统中的进程时间表示进程使用CPU的时间,分为用户时间和内核时间两部分。clock()函数提供了一个简单的接口,返回值描述进程使用的总的CPU时间,计量单位为CLOCKS_PER_SEC。times()函数提供了更详细的进程时间表示,返回值的计量单位由sysconf(SC_CLK_TCK)确定。
通过以上描述,我们可以清楚地理解Linux系统中时间的获取与使用方法,以及不同函数之间的关系,为实际编程提供有力支持。
‘贰’ 杂谈:Linux时间管理之gettimeofday实现
Linux的时间管理是一项核心功能,其中gettimeofday函数作为用户态与内核交互的重要桥梁,其实现方式值得深入探讨。一开始,许多人可能会以为gettimeofday直接调用系统调用,然而事实并非如此。实际上,glibc为用户提供了一层封装,通过调用内核提供的其他函数实现gettimeofday的功能。以glibc2.35为例,其在time目录下的gettimeofday.c文件中实现了这一功能,它通过调用内核的__clock_gettime函数来获取当前时间。进一步探索__clock_gettime函数的实现,我们发现其最终通过调用__clock_gettime64函数来完成时间获取。
__clock_gettime64函数的实现位于glibc2.35/sysdeps/unix/sysv/linux/clock_gettime.c文件中。在函数实现过程中,我们关注到函数的实现逻辑中包含了一个分支,涉及到了一个叫做vdso(虚拟动态共享对象)的概念。vdso是一种优化机制,它利用内存映射技术将内核数据直接映射到用户空间,从而避免了系统调用的开销,极大地提高了性能。为了了解系统中支持vdso的系统调用,可以查阅相关文档或使用特定命令进行查询。
内核态方面,Linux通过周期定时器进行时间更新,其中tick_sched_timer函数在更新系统状态时也参与时间维护。在update_vsyscall函数中,内核会更新vdso的数据结构,这表明即使在不考虑NOHZ情况的场景下,系统也支持正常的中断调用以进行时间更新。
综上所述,Linux的时间管理涉及内核与用户态之间的复杂交互,其中gettimeofday函数的实现展示了这种交互的层次性和优化策略。从用户态的glibc封装到内核态的时间更新机制,每一个环节都体现了Linux在设计上的精妙与高效。对于深入理解Linux内核和系统编程而言,这些细节是不可忽视的。然而,要完全掌握这些内容,需要对glibc结构组织、vdso机制以及内核时间更新等概念有深入的理解。