Linux下使用select实现超级定时器
在编写程序时,我们经常回用到定时器。本文讲述如何使用select实现超级时钟。使用select函数,我们能实现微妙级别精度的定时器。同时,select函数也是我们在编写非阻塞程序时经常用到的一个函数。
首先看看select函数原型如下:
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
说明:1)select函数使用了一个结构体timeval作为其参数。
2)select函数会更新timeval的值,timeval保持的值为剩余时间。
如果我们指定了参数timeval的值,那么在时间耗尽后,select函数便返回,基于这一点,我们可以利用select实现精确定时。
timeval的结构如下:
struct timeval{
long tv_sec;/*secons*
long tv_usec;/*microseconds*/
}
我们可以看出其精确到microseconds也即微妙。
Linux环境下可以有多种方法实现定时。
一、秒级定时器
void seconds_sleep(unsigned seconds){struct timeval tv;tv.tv_sec=seconds;tv.tv_usec=0;int err;do{ err=select(0,NULL,NULL,NULL,&tv);}while(err<0 && errno==EINTR);}二、毫秒级别定时器
void milliseconds_sleep(unsigned long mSec){struct timeval tv;tv.tv_sec=mSec/1000;tv.tv_usec=(mSec%1000)*1000;int err;do{ err=select(0,NULL,NULL,NULL,&tv);}while(err<0 && errno==EINTR);}三、微妙级别定时器
void microseconds_sleep(unsigned long uSec){struct timeval tv;tv.tv_sec=uSec/1000000;tv.tv_usec=uSec%1000000;int err;do{ err=select(0,NULL,NULL,NULL,&tv);}while(err<0 && errno==EINTR);}
现在我们来编写几行代码看看定时效果吧。
#include <stdio.h>#include <sys/time.h>#include <errno.h>int main(){ int i; for(i=0;i<5;++i){printf("%d\n",i);//seconds_sleep(1);//milliseconds_sleep(1500);microseconds_sleep(1900000); }}
我们的超级定时器到此就结束了。短小精悍吧,简单就好!
作者:Viidiot 微信公众号:linux-code