首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

再问定时器-setitimer有关问题

2012-02-06 
再问定时器-setitimer问题#includestdio.h#includetime.h#includesys/time.h#includestdlib.h#inc

再问定时器-setitimer问题
#include   <stdio.h>
#include   <time.h>
#include   <sys/time.h>
#include   <stdlib.h>
#include   <signal.h>

bool   bTimeOver   =   false;

void   set_timer()
{
                struct   itimerval   itv,   oldtv;
                itv.it_value.tv_sec   =   5;
                itv.it_value.tv_usec   =   0;
                itv.it_interval.tv_sec   =   0;   //只执行一次
                itv.it_interval.tv_usec   =   0;
               
                setitimer(ITIMER_PROF,&itv,oldtv);  
}

void   sigalrm_handler(int   sig)
{
                bTimeOver   =   true;
                printf( "timer   signal..   %d\n ",   count);
}

void   init_sigaction(void)  
{  
              struct   sigaction   act;  
              act.sa_handler=sigalrm_handler;  
              act.sa_flags=0;  
              sigemptyset(&act.sa_mask);  
              sigaction(SIGPROF,&act,NULL);  
}  

int   main()
{
                init_sigaction();
                set_timer();
                while   (!bTimeOver)
                {}
                exit(0);
}

这是通用的处理定时器的程序,请各位测试一些,时间到是bTimeOver   =   true,但为什么在main函数中调不出while循环?

在跟踪的时候发现定时器到时bTimeOver   会被置位true,但是就是跳不出while循环,请问是那个地方的问题,还是setitimer的用法没有对,请大家测试一下这个程序是否是我说的一样?再次恳求高手测试一下,给我指点。


[解决办法]
SIGALRM属于“不可靠信号”,进程每次处理信号后,就将对信号的响应设置为默认动作;因此,用户如果不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号。


/*
* testtimer.c - test linux timer
*
*/
/*
* 下面是关于setitimer调用的一个简单示范,在该例子中,每隔一秒发出一个SIGALRM,每隔0.5秒发出一个SIGVTALRM信号
* 此函数的问题,如果在sigroutine中的printf中没有 '\n ',函数无法正常运行,怀疑和缓冲区有关
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/signal.h>
#include <sys/time.h>


void sigroutine(int signo){
printf( "Catch a signal -- SIGALRM %d \n ", signo);
signal(SIGALRM, sigroutine);
return;
}

int main()
{
struct itimerval value1, ovalue;

printf( "process id is %d \n ", getpid());

signal(SIGALRM, sigroutine);

value1.it_value.tv_sec = 0;
value1.it_value.tv_usec = 200000;
value1.it_interval.tv_sec = 0;
value1.it_interval.tv_usec = 200000;
setitimer(ITIMER_REAL, &value1, &ovalue);

for(;;)
;

}


------解决方案--------------------


btw: while循环中是不是需要一个分号,
[解决办法]
SIGALRM属于“不可靠信号”,进程每次处理信号后,就将对信号的响应设置为默认动作;因此,用户如果不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号。

--------------------------------------

signal 存在你说的这种情况。
但sigaction设置的信号句柄不存在你所的情况。响应信号后,并不恢复设置为默认。
[解决办法]
我在cygwin下的结果:

/*
* test.c
*
*/

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

#define DEBUG

int iTimeOver=0;

void set_timer()
{
struct itimerval itv, oldtv;

#ifdef DEBUG
printf( "[ test.c ] start run set_timer() \n ");
#endif

itv.it_value.tv_sec = 5;
itv.it_value.tv_usec = 0;
itv.it_interval.tv_sec = 5; //只执行一次
itv.it_interval.tv_usec = 0;

setitimer(ITIMER_PROF, &itv, &oldtv);

#ifdef DEBUG
printf( "[ test.c ] exit set_timer() \n ");
#endif

}

void sigalrm_handler(int sig)
{
#ifdef DEBUG
printf( "[ test.c ] start run sigalrm_handler() \n ");
#endif

iTimeOver = 1;
printf( "timer signal.. %d\n ", sig);

#ifdef DEBUG
printf( "[ test.c ] exit sigalrm_handler() \n ");
#endif
}

void init_sigaction( void )
{
struct sigaction act;

#ifdef DEBUG
printf( "[ test.c ] start run init_sigaction() \n ");
#endif

act.sa_handler = sigalrm_handler;
act.sa_flags = 0;
if( !sigemptyset(&act.sa_mask) )
printf( "sigemptyset() returen error \n ");
if( !sigaction(SIGPROF, &act, NULL) )
printf( "sigaction() returen error \n ");

#ifdef DEBUG
printf( "[ test.c ] exit init_sigaction() \n ");
#endif
}

int main( void )
{
init_sigaction();
set_timer();
while(1)
{
if( iTimeOver )
break;
}

exit(0);
}

/*END*/


[ test.c ] start run init_sigaction()
sigemptyset() returen error
sigaction() returen error
[ test.c ] exit init_sigaction()
[ test.c ] start run set_timer()
[ test.c ] exit set_timer()

热点排行