[linux c/c++] linux下定时器的使用

您所在的位置:网站首页 ros定时器 [linux c/c++] linux下定时器的使用

[linux c/c++] linux下定时器的使用

#[linux c/c++] linux下定时器的使用| 来源: 网络整理| 查看: 265

前言:

linux下,定时器有三种实现:

1)使用posix的定时器,相关接口为 timer_create

2)使用alarm函数进行计时,alarm函数计时满后会发送ALARM信号,注册信号处理函数即可;

3)使用linux内核的原生timer,需要引入内核模块,头文件为 linux/timer.h

C++ 封装posix: template class MyTimer { public: typedef void (*TimerHandler)(union sigval); public: MyTimer(); ~MyTimer(); void Init(bool triggeronstart,long long interval,TimerHandler routine,std::shared_ptr routineArgs,std::string desc); void Delete(); public: std::string m_desc; private: TimerHandler m_routine; bool m_triggerOnStart = false; long long m_interval; //ms timer_t m_timerid; std::shared_ptr m_routineArgs; }; template MyTimer::MyTimer() { } template MyTimer::~MyTimer() { } template void MyTimer::Init(bool triggeronstart,long long interval,TimerHandler routine,std::shared_ptr routineArgs,std::string desc) { m_triggerOnStart = triggeronstart; m_interval = interval; m_routine = routine; m_routineArgs = routineArgs; m_desc = desc; int ret = 0; struct sigevent sev; memset(&sev, 0, sizeof(struct sigevent)); sev.sigev_notify = SIGEV_THREAD; sev.sigev_notify_function = m_routine; sev.sigev_value.sival_ptr = m_routineArgs.get(); if(ret = timer_create(CLOCK_REALTIME,&sev,&m_timerid)) { assert(ret); } struct itimerspec its; its.it_interval.tv_sec = m_interval/1000; its.it_interval.tv_nsec = (m_interval%1000)*1000000; if(m_triggerOnStart){ its.it_value.tv_sec = 0; its.it_value.tv_nsec = 0; }else{ its.it_value.tv_sec = its.it_interval.tv_sec; its.it_value.tv_nsec = its.it_interval.tv_nsec; } if(ret = timer_settime(m_timerid, 0, &its, NULL)) { assert(ret); } } template void MyTimer::Delete() { timer_delete(m_timerid); }

posix:

以下代码使用回调函数作为定时器触发处理手段。

#include #include #include #include #include struct param{ int i; char c; }p; int cnt; void callback(union sigval v){ struct param * pa = (struct param *)v.sival_ptr; printf("callback %c\n",pa->c); } int main(int argc,char ** argv) { restart: cnt = 0; timer_t timerid; struct sigevent sev; memset(&sev, 0, sizeof(struct sigevent)); p.i = 100; p.c = 'c'; sev.sigev_notify = SIGEV_THREAD; sev.sigev_notify_function = callback; sev.sigev_value.sival_ptr = &p; if(-1 == timer_create(CLOCK_REALTIME,&sev,&timerid)){ printf("timer_create fail"); } struct itimerspec its; its.it_value.tv_sec = 1; its.it_value.tv_nsec = 0; its.it_interval.tv_sec = 1; its.it_interval.tv_nsec = 0; if(-1==timer_settime(timerid, 0, &its, NULL)){ printf("timer_settime fail"); } while(1) { sleep(10); cnt++; if(cnt == 2){ // 20秒后关闭定时器 timer_delete(timerid); } else if(cnt == 4){ // 40秒后重新创建定时器 goto restart; } } }

alarm: //功能描述:在5s内轮询产生的随机数(1s生产一个随机数),判断随机数是不是100的整数倍,如果是,则输出定时器剩余时间,如果不是,继续 #include #include #include #include enum{ TIMER_HANDLER=1, //来自中断处理函数跳转点 }; #define SAVE_SIGMASK 1 long lrandom; //随机数 int remain; //剩余时间 void endup(void); void do_clean(void); void timer_handler(void); jmp_buf sv_p1; int main(int argc,char ** argv) { int interval=5;//多久中断超时一次 int iRet; signal(SIGALRM,(void *)timer_handler); //setjmp(sv_p1); //不使用 iRet = sigsetjmp(sv_p1,SAVE_SIGMASK); if(iRet == TIMER_HANDLER) { //从中断处理函数跳过来的 printf("jump from void timer_handler(void)\n"); } else { //从其他地方跳过来的 } alarm(interval);//开始计时 while(1) { sleep(1); lrandom=random(); int yushu; yushu=lrandom%100;//求余数 printf("yushu = [%ld],lrandom = [%ld]\n",yushu,lrandom); if(yushu==0) { //整除了 remain = alarm(0);//cancle counter,return remain seconds printf("got a number which can be divided by 100 , %d seconds remaining,num is [%ld]\n",remain,lrandom); alarm(interval); //重置定时器 } } } void timer_handler(void) { printf("time out\n"); //1.end of process //endup(); //2.jump to somewhere,goto 只能在当前栈内跳转,栈外跳转使用longjmp系列, //这里使用siglongjmp和sigsetjmp,因为使用longjmp和setjmp在入中断处理函数后, //会自动把中断掩码清0,这样可屏蔽中断就全都被关闭了,下次再满足中断条件也不会入中断了 printf("goto save point 1\n"); //longjmp(sv_p1,TIMER_HANDLER) //不使用 siglongjmp(sv_p1,TIMER_HANDLER);//TIMER_HANDLER为返回值,这个值作为sigsetjmp的返回值,用来判断跳转点 } void endup(void) { do_clean(); exit(-1); } void do_clean(void) { }

原生定时器(saw timer): #include #include #include #include static inline void Start_timer(struct timer_list *timer,unsigned long msec); static inline void Init_timer(struct timer_list *timer,Handler routine,unsigned long argument); static inline void Cancle_timer(struct timer_list *timer); typedef void (*Handler) (void *); struct timer_class{ struct timer_list identity; char * desc; unsigned long interval; Handler routine; }timer1; int main (int argc,char ** argv) { timer1.desc="timer used for xxx\n"; timer1.interval=1000; timer1.routine=(Handler)time_out_handler; //1.INIT A TIMER Init_timer(&(timer1.identity),timer1.routine,(unsigned long)timer1); //2.START A TIMER Start_timer(&(timer1.identity),timer1.interval); //3.have a sleep while(1) sleep(1); } void time_out_handler(struct timer_class *argu) { arug=(struct timer_calss *)argu; //restart timer Start_timer(argu->interval); argu->interval *=2; // printf("time out! timer set to %ld\n",argu->interval); } static inline void Start_timer(struct timer_list *timer,unsigned long msec) { mod_timer(timer,jiffies + msec_to_jiffies(msec) + 1); } static inline void Init_timer(struct timer_list *timer,Handler routine,unsigned long argument) { setup_timer(timer,routine,argument); } static inline void Cancle_timer(struct timer_list *timer) { del_timer_sync(timer); }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3