当前位置: 技术问答>linux和unix
怎样在Linux下实现精确定时器啊?如VC的TimeSetEvent和TimeKillEvent!
来源: 互联网 发布时间:2015-09-18
本文导语: 请问在Linux下有没有该类型的函数?用SetTimer达不到要求,我需要精确到毫秒。 | 呵呵,你的问题先是要毫秒级,那是不行的,linux的内核时钟刷新率是10ms(x86平台)。 但如果40ms那当然是可以...
请问在Linux下有没有该类型的函数?用SetTimer达不到要求,我需要精确到毫秒。
|
呵呵,你的问题先是要毫秒级,那是不行的,linux的内核时钟刷新率是10ms(x86平台)。
但如果40ms那当然是可以的,因为那是4个10ms。
处理过程其实就是安装一个SIGALRM的信号处理函数。
1.#include
2.调用setitimer安装定时器:
它有三个参数第一个设ITIMER_REAL,第二和三个参数是新的时钟间隔和之前设置的时钟间隔。
struct itimerval {
struct timeval it_interval; //设为时钟间隔 40ms,既it_interval.tv_sec=0;it_interval.tv_usec=40*1000; tv_usec是微秒
struct timeval it_value; //设为第一次触发的时钟间隔,其实只被执行一次,以后按照it_interval的值,这里你也可以同上设。
}
3.调用sigaction安装SIGALRM的处理函数,我就不细说了
但如果40ms那当然是可以的,因为那是4个10ms。
处理过程其实就是安装一个SIGALRM的信号处理函数。
1.#include
2.调用setitimer安装定时器:
它有三个参数第一个设ITIMER_REAL,第二和三个参数是新的时钟间隔和之前设置的时钟间隔。
struct itimerval {
struct timeval it_interval; //设为时钟间隔 40ms,既it_interval.tv_sec=0;it_interval.tv_usec=40*1000; tv_usec是微秒
struct timeval it_value; //设为第一次触发的时钟间隔,其实只被执行一次,以后按照it_interval的值,这里你也可以同上设。
}
3.调用sigaction安装SIGALRM的处理函数,我就不细说了
|
#include
#include
#include
void Timer(int sec, long usec)
{
struct timeval tvSelect;
tvSelect.tv_sec = sec;
tvSelect.tv_usec = usec;
select(FD_SETSIZE, NULL, NULL, NULL, &tvSelect);
};
int main()
{
printf("--- begin ---n");
Timer(3, 1000*500);
printf("--- bye ---n");
}
#include
#include
void Timer(int sec, long usec)
{
struct timeval tvSelect;
tvSelect.tv_sec = sec;
tvSelect.tv_usec = usec;
select(FD_SETSIZE, NULL, NULL, NULL, &tvSelect);
};
int main()
{
printf("--- begin ---n");
Timer(3, 1000*500);
printf("--- bye ---n");
}
|
楼主的意思好像不是特别的明确,你说的定时究竟是指定某个确定的时间还是执行某个延时,如果是制定某个确定时间的话,高精度没什么意义,如果确实需要这么做也可以分两部分,在一个粗略的时间上定时,再用一个精确的时间来延时执行同步,Ropyn(剑心) 指出的内核时钟刷新率是10ms,是内核定时中断的频率,这个可以看作粗略的定时,再精确的延时同步,可以用udelay 是个忙等函数,可以用于us的延时,此时内核具有不可抢占性,应该可以满足需要的。
|
两个问题,你改完再试试。
1.
iRet = setitimer(ITIMER_REAL, &tv, &tv);
改为
struct itimerval oldtv;
iRet = setitimer(ITIMER_REAL, &tv, &oldtv);
2.
siga.sa_flags = 0;
改为
siga.sa_flags = SA_RESTART;
这些代码只能调一次。
1.
iRet = setitimer(ITIMER_REAL, &tv, &tv);
改为
struct itimerval oldtv;
iRet = setitimer(ITIMER_REAL, &tv, &oldtv);
2.
siga.sa_flags = 0;
改为
siga.sa_flags = SA_RESTART;
这些代码只能调一次。
|
你可以使用select函数来实现定时器的功能
|
setitimer
|
signal(SIGALRM, handler);
alarm(N);
alarm(N);
|
高精度的化,用 select 。。。2.6 内核专门把 Hz 提高到 1000,就是提供高精度 select 用的。
|
对。2.6 内核把 x86 平台的内核中断频率提高到了 1000 Hz
|
setittimer可以到。
用信号
Ropyn(剑心) 说得对。
用信号
Ropyn(剑心) 说得对。