本文主要介绍Linux下高精度时间函数,及相关的具有超时机制的函数,对定时器也进行简单的介绍。
在linux下一般可用的精度最高的时间插口是gettimeofday,它返回一个timeval结构,其精度为us,即10-6秒,大多数情况这个精度早已够用了。不过有时为了更高的精度,例如毫秒级的时间精度,我们需求探求Linux为我们提供的时间调用。
首先介绍structtimespec结构查看系统版本linux,这个结构体有两个成员,一个是秒,一个是毫秒。
在librt库中,提供了高精度的时间函数,分别是:
long clock_gettime(clockid_t ,struct timespec*)
获取特定时钟的时间,时间通过fp结构传回,目前定义了6种时钟,分别是
CLOCK_REALTIME 系统当前时间,从1970年1.1日算起 CLOCK_MONOTONIC 系统的启动时间,不能被设置 CLOCK_PROCESS_CPUTIME_ID 进程运行时间 CLOCK_THREAD_CPUTIME_ID 线程运行时间 CLOCK_REALTIME_HR CLOCK_REALTIME的高精度版本 CLOCK_MONOTONIC_HR CLOCK_MONOTONIC的高精度版本
获取特定时钟的时间精度:
long clock_getres(clockid_t )
设置特定时钟的时间:
long clock_settime(clockid_t ,struct timespec*)
休眠time手指定的时间,假如遇见讯号中断而提早返回,则由left_time返回剩余的时间:
long clock_nanosleep(clockid_t ,int flag,timespec* time,timespec* left_time)
有了这种个时间函数然后,我们再来看下怎样实现一些不同精度的简单的定时器。
最粗糙的定时器可以由sleep来实现,其精度为秒级,系统也提供像nanosleep,usleep,ualarm等,其实你乐意也可以由poll(ms)、select(us)、ppoll或pslect(ns)等来实现各类精度的sleep。通过这种高精度的sleep函数,也可以实现一系统不同精度的定时器。
通过上述sleep实现的定时器一般须要我们自行进行编码中国linux操作系统,但是过多的sleep也会造成某个cpu不能充分的借助,对于大量定时器的场合就须要当心编撰代码,这些方法一般以单独线程控制或主循环协程的形式查看什么定时器到期。总体来说,实现复杂,效率较低,但是也没有一种好的定时器到期时的通知机制,一般是被动由定时器线程强行执行或则自身线程在线程主循环中检测到期的定时器并执行。
下边我们将探求一下由操作系统提供的一些定时器机制。操作系统提供了两个种类的定时器,一种是显式的定时器,另一种是隐藏在调用的超时时间或特定文件属性之上。前者我们在后面早已看到过,例如select、套接字描述符的超时属性,这种须要在不同的编程领域去积累,其实它们也有各自的精度。下边我们主要介绍一下系统提供的显式的定时器。
Linux系统为每位进程提供了三个间隔定时器,精度为us。定时器到期时将触发相应的讯号,定时器可能会重新开始,值得注意的是,fork生成的子进程并不承继父进程的定时器。
int getitimer(int type, itimerval* val) int setitimer(int type, itimerval* nval, itimerval* oval)
itimerval有两个成员linux 定时器 精度,it_interval和it_value,均为timeval类型,后者保存的是上次定时器的定时间隔,前者为本次超时时的定时间隔。也就是说,定时器将从it_value降低,当变为0时,发送讯号,并从it_interval取值,重新开始定时器。假如val被置为0,则停止定时器。
getitimer()用于设置一个定时器,而setitimer用于更改早已设置的定时器,假如在设置时定时器仍未超时,则剩余时间保存于oval。
定时器定时器三个定时器分别是:
ITIMER_REAL 以系统时间递减,超时时投递SIGALRM信号 ITIMER_VIRTUAL 以进程执行时间递减,超时时投递 SIGVTALRM ITIMER_PROF 当进程执行或进程执行系统调用时均递减,超时时投递SIGPROF信号。
据悉Posix1.b中为我们提供了实时高精度的定时工具,精度可以达到毫秒。不过每位进程只能有一个。
int timer_creat() int timer_delete() int timer_gettime() int timer_settime()
具体使用方式不在这儿阐述,可见系统提供的定时器是一种珍视资源,一般只是一种最基本的设施,应用须要使用这个最基本的设施定义多元化的定时器,以满足程序中使用多种及多个定时器。其实系统提供的定时器须要人工设置讯号处理等相关工作linux 定时器 精度,须要专门处理讯号的代码,这个在一定程度上降低了程序的复杂性。因而说来,从sleep族的定时器到系统显式的定时器,各有优劣点,使用时按照情况权衡选择。