linux应用程序中定时器的实现

本文介绍了一种使用信号和定时器实现应用程序定时功能的方法。通过设置SIGUSR1和SIGALRM信号处理函数,结合setitimer和getitimer函数,实现了每秒触发一次信号并计时的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近看了下应用程序定时器的实现方法,与大家分享如下:

/*我们在使用signal和时钟相关的结构体之前,需要包含这两个头文件*/

#include <signal.h>

#include <sys/time.h>

/*声明信号处理函数,信号相关内容将在第八章同步机制中讲述,读者在这里只要明白这个函数是

在进程收到信号的时候调用就可以了*/

static void sig_handler(int signo);

long lastsec,countsec;   /*这两个变量分别用来保存上一秒的时间和总共花去的时间*/

int main(void)

{

           struct itimerval v;         /*定时器结构体,结构体内容请参阅第三节中的介绍*/

            long nowsec,nowusec;    /*当前时间的秒数和微秒数*/

         /*注册SIGUSR1和SIGALARM信号的处理函数为sig_handler*/

         if(signal(SIGUSR1,sig_handler)==SIG_ERR)

        {

                    printf("Unable to create handler for SIGUSR1\n");

                    exit(0);

        }

         if(signal(SIGALRM,sig_handler)==SIG_ERR)

        {

                    printf("Unable to create handler for SIGALRM\n");

                    exit(0);

        }

         /*初始化定时器初值和当前值*/

        v.it_interval.tv_sec=9;

        v.it_interval.tv_usec=999999;

        v.it_value.tv_sec=9;

        v.it_value.tv_usec=999999;

       

/*调用setitimer设置定时器,并将其挂到定时器链表上,这个函数的三个参数的含义分

别是设置ITIMER_REAL类型的定时器,要设置的值存放在变量v中,该定时器设置前

的值在设置后保存的地址,如果是这个参数为NULL,那么就放弃保存设置前的值*/

           setitimer(ITIMER_REAL,&v,NULL);

   

            lastsec=v.it_value.tv_sec;

           countsec=0;

/*该循环首先调用getitimer读取定时器当前值,再与原来的秒数比较,当发现已经过了

一秒后产生一个SIGUSR1信号,程序就会进入上面注册过的信号处理函数*/

           while(1)

           {

                       getitimer(ITIMER_REAL,&v);

                       nowsec=v.it_value.tv_sec;

                       nowusec=v.it_value.tv_usec;

                        if(nowsec==lastsec-1)

{

                           /*每过一秒,产生一个SIGUSR1信号*/

                                    raise(SIGUSR1);  

                                    lastsec=nowsec;

                                   countsec++;       /*记录总的秒数*/

                       }

           }    

}

/*信号处理函数*/

static void sig_handler(int signo)

{

           switch(signo)

           {

                        /*接收到的信号是SIGUSR1,打印One second passed*/

                       case SIGUSR1:

                                  printf("One second passed\n");

                                   break;

                        /*定时器定时到达*/

                       case SIGALRM:

                       {

                                   printf("Timer has been zero,elapsed %d seconds\n",countsec);

                                    lastsec=countsec;

                                   countsec=0;

                                   break;

                       }

           }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值