singal函数用来绑定信号处理器函数,这里绑定的是timer,被绑定的函数必须固定为返回值void、参数int.
只需要alarm(时间)就设置了,可能由于getchar需要进入中断导致信号被挂起所以没反应,可以试试把getchar换成别的东西来延时看看。
关于更多Linux的学习,请查阅书籍《linux就该这么学》。
linux下使用select实现精确定时器在编写程序时,我们经常回用到定时器。本文讲述如何使用select实现超级时钟。使用select函数,我们能实现微妙级别精度的定时器。同时,select函数也是我们在编写非阻塞程序时经常用到的一个函数。
首先看看select函数原型如下:
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
参数说明:
slect的第一个参数nfds为fdset集合中最大描述符值加1,fdset是一个位数组,其大小限制为__FD_SETSIZE(1024),位数组的每一位代表其对应的描述符是否需要被检查。
select的第二三四个参数表示需要关注读、写、错误事件的文件描述符位数组,这些参数既是输入参数也是输出参数,可能会被内核修改用于标示哪些描述符上发生了关注的事件。所以每次调用select前都需重新初始化fdset。
timeout参数为超时时间,该结构会被内核修改,其值为超时剩余的时间。
利用select实现定时器,需要利用其timeout参数,注意到:
1)select函数使用了一个结构体timeval作为其参数。
2)select函数会更新timeval的值,timeval保持的值为剩余时间。
如果我们指定了参数timeval的值,而将其他参数都置为0或者NULL,那么在时间耗尽后,select函数便返回,基于这一点,我们可以利用select实现精确定时。
timeval的结构如下:
struct timeval{
long tv_sec;/*secons*
long tv_usec/*microseconds*/
}
我们可以看出其精确到microseconds也即微妙。
一、秒级定时器
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=0i<5++i){
printf("%d\n",i)
//seconds_sleep(1)
//milliseconds_sleep(1500)
microseconds_sleep(1900000)
}
}
注:timeval结构体中虽然指定了一个微妙级别的分辨率,但内核支持的分别率往往没有这么高,很多unix内核将超时值向上舍入成10ms的倍数。此外,加上内核调度延时现象,即定时器时间到后,内核还需要花一定时间调度相应进程的运行。因此,定时器的精度,最终还是由内核支持的分别率决定。
试试alarm()与signal(),例子可以网上搜搜NAME
alarm - set an alarm clock for delivery of a signal
SYNOPSIS
#include <unistd.h>
unsigned int alarm(unsigned int seconds)
DESCRIPTION
alarm() arranges for a SIGALRM signal to be delivered to the calling process in seconds seconds.
If seconds is zero, no new alarm() is scheduled.
In any event any previously set alarm() is canceled.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)