最近写的很多东西都需要定周期的做一些处理,我用到了setitimer这个Linux的系统函数,使用这个函数真真的是让我又爱又恨。
在说这个定时器之前呢,先要说说与它相关的Linux的系统信号,和信号相关的函数。
signal()函数可以将Linux的信号与一个函数相关联,比如我们要用的定时器:signal(SIGALRM, on_function);这样的话,当定时器计时时间到了之后,就会产生一个SIGALRM的系统信号,有了这个信号就会走进on_function函数中。
再说说setitimer这个函数本身:
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
setitimer()第一个参数which指定定时器类型,第二个参数是结构itimerval的一个实例,第三个参数可不做处理。
setitimer()调用成功返回0,否则返回-1。
struct itimerval {
struct timeval it_interval;
struct timeval it_value;
};
struct timeval {
long tv_sec;
long tv_usec;
};
it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;两者都清零,则会清除定时器。
tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us。
ovalue用来保存先前的值,常设为NULL。
这个函数使用起来非常方便,只要在你需要定时的地方调用setitimer函数,给它一个定时时间,这样它就一到时间就有一个闹钟信号,只要你不去停止它,它就会周期性的响起闹钟。那么怎么停呢,我的做法非常野蛮也非常有效,将定时时间全都置为0,就妥妥的了。
但是呢,一个进程只能有一个定时器,如果在一个进程中多次使用它,后面的就会把前面的覆盖掉,要想在一个进程中使用多个定时器,那就对不起了,你需要自己实现,其实实现起来也并不麻烦,网上有很多例子可以参考,就是写一个链表。