|
|
|
|
 select的定时问题 - yeahnix [ 2005-09-22 15:03 | 2,169 byte(s)]
 Re: select的定时问题 - lonelyflyer [ 2005-09-22 15:43 | 171 byte(s)]
 Re: select的定时问题 - yeahnix [ 2005-09-22 17:46 | 244 byte(s)]
 Re: select的定时问题 - lonelyflyer [ 2005-09-22 18:02 | 41 byte(s)]
 Re: select的定时问题 - yeahnix [ 2005-09-23 12:53 | 3 byte(s)]
|
|
|
|
[Original]
[Print]
[Top]
|
应用程序定时一般可以使用alarm和setitimer,alarm可以认为是用setitimer中的ITIMER_REAL实现的,setitimer还有另外两种定时器,ITIMER_VIRTUAL, ITIMER_PROF,这三种定时器定时时间到的时候,向应用程序分别发送SIGALRM, SIGVTALRM, SIGPROF信号,因此可以设定对应的信号处理函数。
加入select来实现定时后,测试时发现一个问题,代码如下:
void sig_timer(int signo)
{
int esaved;
esaved = errno;
write(STDOUT_FILENO, "sig timer triggered
", 20);
errno = esaved;
}
int main(int argc, char * argv[])
{
struct timeval tv_timeout;
struct itimerval old, new;
int retval;
if (signal(SIGPROF, sig_timer) == SIG_ERR)
{
printf("Can't catch SIGPROF
");
}
new.it_interval.tv_usec = 0;
new.it_interval.tv_sec = 0;
new.it_value.tv_usec = 0;
new.it_value.tv_sec = (long int) 2;
if (setitimer (ITIMER_PROF, &new, &old) < 0)
{
printf("Set itimer wrong
");
}
else
{
printf("Set itimer success
");
}
tv_timeout.tv_sec = 3;
tv_timeout.tv_usec = 0;
retval = select (1, NULL, NULL, NULL, &tv_timeout);
if ((retval < 0) && (errno == EINTR))
{
printf(" signal interrupted select
");
}
else if( retval == 0)
{
printf("Time out of select
");
}
while(1)
;
return 0;
}
在上述代码中,程序在select后,先返回并打印消息,而信号处理函数似乎在select后又多等了两秒才触发,不知道是什么原因。
而如果将ITIMER_PROF改为ITIMER_REAL则运行正常,信号将中断select的运行。是否是select本身使用了setitimer,但是setitimer也只能使用一次阿
还请各位大侠赐教
|
|
|
----
just do it
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
ITIMER_PROF是计算的当前进程占用的CPU时间,超出才触发
ITIMER_REAL才是一般的时间片
这点 select 阻塞和 whie(1); 循环的效果是完全不一样的
|
|
|
----
OpenH323 is buggy ACE is memory greedy
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
也就是说,实际上select阻塞时并没有和setitimer产生冲突,select阻塞和sleep效果差不多,对进程执行时间产生的影响很少。
btw:select阻塞实现的原理是什么样的呢?
看内核中的代码好像是直接schedule_timeout,在c库中是否有对阻塞的包装呢?
|
|
|
----
just do it
|
|
[Original]
[Print]
[Top]
|
|
|