linux中定时器 setitimer()

参考文档

(1)http://www.cnblogs.com/dandingyy/articles/2653218.html

(2)http://baike.baidu.com/link?url=_npJrTewl6jAk2B0G-KDiluRkC09xDTezsnTy0bbqsdcqjTlMQMvQY-of9mLbcIeoxqqiW2DzwMT5xaqOqO9WK

(3)http://blog.csdn.net/liangyamin/article/details/7320608


在参考文献(1)中提到了“在linux下如果定时如果要求不太精确的话,使用alarm()和signal()就行了(精确到秒),但是如果想要实现精度较高的定时功能的话,就要使用setitimer函数。”因为我一开始就查的是setitimer函数,所以这里先介绍下这个函数吧。

一、 函数原型

       int setitimer(intwhich, const struct itimerval *Value, struct itimerval *ovalue);

   调用成功返回0,否则返回-1

     which : 定时器类型,有3种选择

                    ITIMER_REAL:以系统真实事件来计算,它送出SIGALRM信号。

                    ITIMER_VIRTUAL:以该进程在用户态下话费的时间来计算,它送出SIGVTALRM信号。

                    ITIMER_PROF:以该进程在用户态下和内核态下所话费的时间来计算,它送出SIGPROF信号。

      Value:其定义如下

                          struct   itimerval {

                                struct  timeval  it_interval;  // how long to run the first time

                                struct  timeval  it_value;     // after the first time, how long to run next time

                          }


                          struct  timeval {

                                long  tv_sec;    // 秒

                                long  tv_usec;  // 微秒

                          }

     ovalue:用来保存先前的值,一般为NULL。如果不是NULL,将返回计时器原有值。


二、 程序例程

1.  示例1

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <string.h>   
#include <unistd.h>   

#include <errno.h>

void Func1()
{
	static int iCnt1 = 0;
	printf("The %d Times: Hello world in Func1()\n", iCnt1);
	iCnt1++;
}

int main(void)
{
	struct itimerval tv,otv;
	signal(SIGALRM,Func1);
	
	//how long to run the first time
	tv.it_value.tv_sec = 1;
	tv.it_value.tv_usec = 0;
	//after the first time, how long to run next time
	tv.it_interval.tv_sec = 3;
	tv.it_interval.tv_usec = 0;
	
	if(setitimer(ITIMER_REAL, &tv, &otv) != 0)
		printf("setitimer err %d\n", errno);
	
	while(1)
	{
		pause();
	}
}

结果就是每隔3s打印一次内容。当执行完setitimer后,第一次是等1s就开始打印了,但后面每次都等待3s打印。



2. 示例2

#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <string.h>   
#include <unistd.h>   

#include <errno.h>

void Func1()
{
	static int iCnt1 = 0;
	printf("The %d Times: Hello world in Func1()\n", iCnt1);
	iCnt1++;
}

void Func2()
{
	static int iCnt2 = 0;
	printf("The %d Times:Hello world in Func2()\n", iCnt2);
	iCnt2++;
}

int main(void)
{
	struct itimerval tv,otv;
	signal(SIGALRM,Func1);
	
	//how long to run the first time
	tv.it_value.tv_sec = 1;
	tv.it_value.tv_usec = 0;
	//after the first time, how long to run next time
	tv.it_interval.tv_sec = 3;
	tv.it_interval.tv_usec = 0;
	
	if(setitimer(ITIMER_REAL, &tv, &otv) != 0)
		printf("setitimer err %d\n", errno);
	
	//假如说有两个定时,都用setitimer(ITIMER_REAL, &tv, &otv)这种方法定义
	
	struct itimerval tv1,otv1;
	signal(SIGALRM,Func2);

	tv1.it_value.tv_sec = 10;
	tv1.it_value.tv_usec = 0;
	
	tv1.it_interval.tv_sec = 20;
	tv1.it_interval.tv_usec = 0;
	
	if(setitimer(ITIMER_REAL, &tv1, &otv1) != 0)
		printf("setitimer2 err %d\n", errno);
	
	while(1)
	{
		//sleep(1);
		//printf("otv: %d, %d, %d, %d\n", otv.it_value.tv_sec, otv.it_value.tv_usec, otv.it_interval.tv_sec, otv.it_interval.tv_sec);
		pause();
	}
}

这个每次间隔20s进行一次打印,结果如下:


          这里要特别做如下的说明:

          一个进程只能使用一个setitimer函数,这个并不想QT里面的信号与槽的这种机制,其实其只发出一个SIGALRM,与定义了多少个itimerval类型的变量无关。所以如果有两个setitimer函数,第二个函数会把第一次调用时设置的参数给覆盖了。第一次定义的是每个3s执行一次,第二次定义的是每个20s执行一次,实际上程序执行后,打印的节奏确实是20s执行一次。signal函数虽然设置了两次,同样第二次把第一次给覆盖了,当计时时间到了,并不会执行Func1函数,而是会执行Func2函数。


       后面再研究参考文献(1)中提到的alarm()和signal()方法,另外一点就是,setitimer函数底层如何进行微秒级的一个定时的,内核中驱动如何处理的。


欢迎交流共同学习 QQ群:485158261   

                   

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值