栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

linux C定时器总结

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux C定时器总结

概述
linux c本身不支持对timer的封装,使用定时器不像java那样的方便,一般有三种方法使用:1、while+sleep;2、alarm;3、timer_create。下面分别对三种方法进行举例。

一、举例

1、while+sleep

优点是可以完全控制暂停恢复,确定是需要控制线程的生命周期。

#include 

#include 

#include 

#include 

typedef void (*TIMER_CALLBACK)(void);

static int s_wait_time=0;

static TIMER_CALLBACK s_call_back;

static int s_timer_flag=0;

static pthread_t s_pt;

static void sleep_ms(unsigned int msecs)

{

       struct timeval tval;

       tval.tv_sec      = msecs / 1000;

       tval.tv_usec = (msecs * 1000) % 1000000;

       select(0, NULL, NULL, NULL, &tval);

}

//定时器线程

static void* thread_runner(void* param)

{

       int time = 0;

       printf("thread_run:pthread_self()=[%d]n",pthread_self());

       while(s_timer_flag)

       {

              sleep_ms(s_wait_time);

              if(s_call_back!=NULL)

              {

                     s_call_back();

              }

       }

       printf("thread_stop:pthread_self()=[%d]n",pthread_self());

       return NULL;

}

//打开定时器

int starttimer(int time_million_second,TIMER_CALLBACK callback)

{

       s_wait_time=time_million_second;

       s_timer_flag=1;

       s_call_back=callback;

       pthread_create(&s_pt,NULL,thread_runner,NULL);

}

//关闭定时器

int stoptimer()

{

       s_timer_flag = 0;

      

       //暂停定时器也可以结束线程

       //pthread_cancel(s_pt);

}

static void timer_routie()

{

       static int times = 0;

       printf("timer_routie:times=[%d]n",times++);

}

 int  main()

 {

       starttimer(1000,timer_routie);

       sleep(5);

       stoptimer();

       sleep(1);

 }

2、alarm

优点是实现简单,确定是信号会导致sleep和pause提前结束

#include  

#include  

#include  

#include  



typedef void (*TIMER_CALLBACK)(void);



static int s_wait_time=0;

static TIMER_CALLBACK s_call_back;

static int s_timer_flag=0;



void signal_handler(int siganl)

{

       printf("signal_handler:siganl=[%d]n",siganl);

       if(siganl==SIGALRM)

       {

              if(s_call_back!=NULL)

              {

                     s_call_back();

                     alarm(s_wait_time/1000);

              }

       }

}



//打开定时器

int starttimer(int time_million_second,TIMER_CALLBACK callback)

{

       s_call_back=callback;

       s_wait_time=time_million_second;

       signal(SIGALRM,signal_handler);

       alarm(s_wait_time/1000);

}



//关闭定时器

int stoptimer()

{

       s_wait_time=NULL;

}



static void timer_routie()

{

       static int times = 0;

       printf("timer_routie:times=[%d]n",times++);

}



 int  main()

 {

       int count=5;

       starttimer(1000,timer_routie);

      

       //alarm会导致sleep和pause停止阻塞直接返回,所以这里需要循环

       while(count--)

       {

              pause();

       }



       stoptimer();



 }

3、timer_create signal模式,此方式也会导致pause、sleep等函数提前返回

#include 

#include 

#include 

#include 

typedef void (*TIMER_CALLBACK)(void);

static int s_wait_time=0;

static TIMER_CALLBACK s_call_back;

static pthread_t s_pt;

static timer_t s_timerid;;

void signal_handler(int siganl)

{

       printf("signal_handler:siganl=[%d]n",siganl);

       if(siganl==SIGRTMAX)

       {

              if(s_call_back!=NULL)

              {

                     s_call_back();

              }

       }

}

//打开定时器

int starttimer(int time_million_second,TIMER_CALLBACK callback)

{

       s_wait_time=time_million_second;

       s_call_back=callback;

      

       signal(SIGRTMAX,signal_handler);

      

      

       clockid_t clockid=CLOCK_REALTIME;

       struct sigevent sev;

       sev.sigev_notify=SIGEV_SIGNAL;

       sev.sigev_signo=SIGRTMAX;

       sev.sigev_value.sival_ptr=&s_timerid;

       //创建定时器

       timer_create(clockid,&sev,&s_timerid);

      

       int flags=0;

       struct itimerspec new_value;

       new_value.it_value.tv_sec=1;

       new_value.it_value.tv_nsec=0;

       new_value.it_interval.tv_sec=1;

       new_value.it_interval.tv_nsec=1;

       //struct itimerspec old_value;

       //启动定时器

       timer_settime(s_timerid,flags,&new_value,NULL);

}

//关闭定时器

int stoptimer()

{

       timer_delete(s_timerid);

       printf("stoptimer:s_timerid=[%d]n",s_timerid);

}

static void timer_routie()

{

       static int times = 0;

       printf("timer_routie:times=[%d]n",times++);

}

 int  main()

 {

       int count=5;

       starttimer(1000,timer_routie);

       while(count--)

       {

              pause();//timer_create也会触发信号量导致sleep/usleep和pause立刻返回

       }

       stoptimer();

       sleep(10);

 }

4、timer_create thread模式,此模式不会导致sleep和pause提前返回,但是会额外创建线程,使用过多的定时器会额外使用内存。

#include  

#include  

#include  

#include  



typedef void (*TIMER_CALLBACK)(void);



static int s_wait_time=0;

static TIMER_CALLBACK s_call_back;

static pthread_t s_pt;

static timer_t s_timerid;;



void timer_handler(union sigval sig)

{

       printf("signal_handlern");

       if(s_call_back!=NULL)

       {

              s_call_back();

       }

}



//打开定时器

int starttimer(int time_million_second,TIMER_CALLBACK callback)

{

       s_wait_time=time_million_second;

       s_call_back=callback;

      

       clockid_t clockid=CLOCK_REALTIME;

       struct sigevent sev;

       sev.sigev_notify=SIGEV_THREAD;

       sev.sigev_signo=SIGRTMAX;

       sev.sigev_value.sival_ptr=&s_timerid;

       sev.sigev_notify_function=timer_handler;//设置定时器回调

       //创建定时器

       timer_create(clockid,&sev,&s_timerid);

      

       int flags=0;

       struct itimerspec new_value;

       new_value.it_value.tv_sec=1;

       new_value.it_value.tv_nsec=0;

       new_value.it_interval.tv_sec=1;

       new_value.it_interval.tv_nsec=1;

       //struct itimerspec old_value;

       //启动定时器

       timer_settime(s_timerid,flags,&new_value,NULL);

}



//关闭定时器

int stoptimer()

{

       timer_delete(s_timerid);

       printf("stoptimer:s_timerid=[%d]n",s_timerid);

}



static void timer_routie()

{

       static int times = 0;

       printf("timer_routie:times=[%d]n",times++);

}



 int  main()

 {

       int count=5;

       starttimer(1000,timer_routie);

       while(count--)

       {

              pause();//timer_create的thread类型不会触发信号量,也就不会导致sleep/usleep和pause立刻返回

       }

       stoptimer();

       sleep(10);

 }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/867062.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号