当前位置: 技术问答>linux和unix
再问定时器-setitimer问题
来源: 互联网 发布时间:2016-02-26
本文导语: #include #include #include #include #include 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;...
#include
#include
#include
#include
#include
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.. %dn", 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的用法没有对,请大家测试一下这个程序是否是我说的一样?再次恳求高手测试一下,给我指点。
#include
#include
#include
#include
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.. %dn", 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
#include
#include
#include
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(;;)
;
}
/*
* testtimer.c - test linux timer
*
*/
/*
* 下面是关于setitimer调用的一个简单示范,在该例子中,每隔一秒发出一个SIGALRM,每隔0.5秒发出一个SIGVTALRM信号
* 此函数的问题,如果在sigroutine中的printf中没有'n',函数无法正常运行,怀疑和缓冲区有关
*/
#include
#include
#include
#include
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(;;)
;
}
|
我在cygwin下的结果:
/*
* test.c
*
*/
#include
#include
#include
#include
#include
#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.. %dn", 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()
/*
* test.c
*
*/
#include
#include
#include
#include
#include
#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.. %dn", 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()
|
btw: while循环中是不是需要一个分号,
|
SIGALRM属于“不可靠信号”,进程每次处理信号后,就将对信号的响应设置为默认动作;因此,用户如果不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号。
--------------------------------------
signal 存在你说的这种情况。
但sigaction设置的信号句柄不存在你所的情况。响应信号后,并不恢复设置为默认。
--------------------------------------
signal 存在你说的这种情况。
但sigaction设置的信号句柄不存在你所的情况。响应信号后,并不恢复设置为默认。