23.1 间隔定时器
setitimer系统调用创建一个间隔式定时器,这种定时器会在未来某个时间点到期,并于此后每隔一段时间到期一次。
which:
- ITIMER_REAL : 创建以真实时间倒计时的定时器。到期后会产生SIGALARM信号并发送给进程。
- ITIMER_VIRTUAL :创建以进程虚拟时间倒计时的定时器。到期时会产生信号SIGVTALRM。
- ITIMER_PROF : 创建一个profiling定时器,以进程时间(用户态和内核态CPU时间的总和)倒计时。到期会发送SIGPROF信号。
这些信号默认会终止进程,需要手动创建处理器函数。
new_value和old_value : 指向itimerval的指针。
new_value的下属结构it_value指定了距离定时器的延迟时间。it_interval若为非零则为会重复到期的定时器。
如果调用setitimer()时将new_value.it_value 的两个字段均置为0,那么会屏蔽任何已有的定时器。
old_value返回前一设置。
getitimer函数可以了解定时器的当前状态,距离下次到期的时间。
更为简单的定时器接口:alarm()
到期会发送SIGALRM信号
alarm()函数和setitimer()函数控制同一个定时器。
23.2 定时器的调度与精度
取决于当前负载和对进程的调度,系统可能会在定时器到期的瞬间(通常是几分之一秒)之后才去调度其所属进程。
但定时器还是会恪守规则。
高精度定时器的精度达到us级是司空见惯的事情,目前的linux内核一般都支持高分辨率定时器。
23.3 为阻塞操作设置超时
实时定时器的用途之一是为了某个阻塞系统调用设置其处于阻塞状态的时间上限。
23.4 暂停运行一段固定时间
低分辨率睡眠:sleep() :
秒级
考虑到可移植性,应避免将sleep()和alarm()以及setitimer混用。
高分辨率睡眠:nanosllep() :
request参数指定需要休眠的时间。
remain返回剩余的休眠时间。
纳秒级时间结构体:
nanosleep和alarm或setitimer混用,也不会危及程序的可移植性。因为SUSv3规定不得使用信号来实现该函数。
23.5 POSIX时钟
POSIX始终支持纳秒级的时间精度,编译时需要加上-lrt
主要有三个函数:
获取时间值,和精度:
clock_getres函数用于获取时钟的分辨率,在res中返回。
设置时间值:
clockid指定了时钟的标识符:
获取特定进程或线程的时钟ID:
这两个函数一看就懂吧
高分辨率休眠的改进版:
默认情况下,由request指定的休眠间隔时间是相对时间,若在flag指定了TIMER_ABSTIME,request则表示clockid时钟所测量的绝对时间,这一特性对于那些需要精确休眠一段时间的应用程序至关重要。
23.6 POSIX间隔式定时器
创建定时器:
timerif返回一个定时器句柄,供后续调用中指代该计时器之用。
evp可决定定时器到期时对应用程序的通知方式,指向sigevent的数据结构。
配备和解除定时器:timer_settime() :
timerid由timer_create返回。
value中包含定时器的新设置,old_value则用于返回前设置。
it_value指定定时器首次到期的时间。若it_interval中任意字段非零,那么就是一个周期性定时器。
flag同上。
获取定时器的当前值:
curr_value指针所指向的itimerspec结构中返回的是时间间隔以及距离下次定时器到期的时间。
删除定时器:timer_delete()
每个POSIX定时器都会消耗少量系统资源,所以一旦使用完毕,应当删除。
通过信号发出通知:
…
定时器溢出:
在捕获或接收信号之前,定时器到期多次。
该函数返回timerid指定定时器的溢出值。
23.7 利用文件描述符进行通知的定时器: timer API
linux内核提供了另一种创建定时器的API。Linux特有的timerfd API,可以从文件描述符中读取其所创建定时器的到期通知。因为可以使用select,poll,epoll将这种文件描述符会同其他描述符一同进行监控,所以非常实用。
三个函数:
clockid见上表。
flags: