• 16定时器


    简单定时器

    #include<unistd.h>

    unsigned int alarm(unsigned int seconds)

          返回上一个alarm等待时间,没有则返回0

          只能设置 1 个定时器,设置第 2 个时会替换第一个

          设置成功后,上一个alarm会失效

          定时事件只执行1次,多次执行需要递归调用

    等待事件到达后,会给进程发送 SIGALRM信号

          捕获 SIGALRM信号并处理

    例子:

    int g_nValue=0;

    void fun(int sig)

    {

          printf("sig:%d ",sig);

          printf("g_nValue=%d ",g_nValue);

    }

    void testAlarm()

    {

          printf("pid:%d ",getpid());

          //printf("1 ");

          int n=0;

          n=alarm(1);

          //printf("%d ",n);

          //printf("2 ");

          signal(SIGALRM,fun);

          //printf("3 ");

          while(1)

          {

               g_nValue++;

          }

    }

    注意:alarm()定时器结束后,才发出SIGALRM信号。如alarm(100),不是启动alarm就发出,而是启动后100秒才发出信号。

    一个定时器多次使用:

    只需在信号处理函数再一次使用alarm()即可。

    void fun(int sig)

    {

          printf("sig:%d ",sig);

          printf("g_nValue=%d ",g_nValue);

          alarm(1);

    }

    alarm只能一个定时器,如果要该定时器不同秒数启动。即实现多个定时器的功能。

    方式:设置一个标志位,用来标志秒数

    void fun(int sig)

    {

          static flag=0;

          flag++

          //1秒

          alarm(flag);

          if(flag%2==0)

          {

               //2秒

               alarm(flag);

          }

          if(flag%5==0)

          {   

               //5秒

               alarm(flag);

          }

          //...............

          printf("sig:%d ",sig);

    }

    sleep与定时器的区别:

    sleep是使程序进入休眠状态,即sleep后面的代码不会继续运行,直到休眠结束。

    alarm定时器开始后,代码也会继续往下运行。

    sleep对定时器的影响:

    void fun(int sig)

    {

          //printf("sig:%d ",sig);

          printf("!");

          alarm(1);

    }

    void testAlarm()

    {

          printf("pid:%d ",getpid());

          int n=0;

          n=alarm(1);

          signal(SIGALRM,fun);

          while(1)

          {

               sleep(10);

               printf("@");

          }

    }

    结果输出:

    pid:9282

    !@!@!@.......

    问题:定时器是1秒,sleep是10秒。不应该是10个!才是一个@吗?

    此时就涉及到进程调度问题。程序原是运行态,sleep使程序进入了睡眠态。但是睡眠态无法直接回到运行态,只能到就绪态,等待cpu执行。

    精准定时器

    <sys/select.h>

    <sys/time.h>

    int getitimer(int which, struct itimerval *value)

    int setitimer(int which, struct itimerval *new, struct itimeval *old)

    which取值:提供三种定时器,可以同时存在

    ITIMER_REAL           (0)

    发送信号:SIGALRM

    定义真实CPU时间(所有进程的CPU时间都累计),同 alarm

    ITIMER_VIRTUAL     (1)

    发送信号:SIGVTALRM

    定义进程在用户态下的实际执行时间(只累计自己用户态的CPU时间)

    ITIMER_PROF          (2)

    发送信号:   SIGPROF

    定义进程在用户态和内核态的实际执行时间(只累计自己的CPU时间)

    注意:因为alarm 和ITIMER_REAL都是发出同一个信号SIGALRM,因此larm 和 setitimer(ITIMER_REAL, ...) 不能同时使用

    struct itimerval

    {

          struct timeval it_interval;  //下次定时取值;后续定时间隔时间

          struct timeval it_value;     //本次定时设置值;定时器第一次到达时间

    }

    struct timeval {

            time_t      tv_sec;         /* 秒 */

            suseconds_t tv_usec;        /* 微妙 */

    };

    定时器开始后

    1.  先把 it_value 减少到0

    2.  把 it_interval 复制给 it_value; (it_inverval=0则停止定时器)

    3.  继续下一次定时循环

    例子:

    void func(int sig)

    {

          //printf("sig:%d ",sig);

          switch(sig)

          {

          case SIGALRM:

               {   

                     printf("SIGALRM.... ");

                     break;

               }

          case SIGVTALRM:

               {   

                     printf("SIGVTALRM.... ");

                     break;

               }

          case SIGPROF:

               {   

                     printf("SIGPROF.... ");

                     break;

               }

          }

    }

    void testMircoTimer()

    {

          printf("pid:%d ",getpid());

          struct itimerval new;

          //本次定时器间隔秒数

          new.it_interval.tv_sec=0;

          new.it_interval.tv_usec=500*1000;    //0.5

         

          //下次定时器间隔秒数

          new.it_value.tv_sec=1;

          new.it_value.tv_usec=500*1000; //0.5

         

          //创建三种定时器

          setitimer(ITIMER_REAL,&new,NULL);

          setitimer(ITIMER_VIRTUAL,&new,NULL);

          setitimer(ITIMER_PROF,&new,NULL);

         

          signal(SIGALRM,func);

          signal(SIGVTALRM,func);

          signal(SIGPROF,func);

         

          while(1)

          {

              

          }

    }

  • 相关阅读:
    c++ 中bool 的默认值
    cocos2d CCLOG格式符号表
    c++数组指针bug
    cocos2d-x-2.2.6创建工程
    Nape实现坐标旋转角度回弹
    haxe 中使用音效
    haxe 嵌入swf 读取里面的内容
    haxe 配置
    Spring Tool Suite(STS)基本安装配置
    git提交忽略文件.gitignore内容
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9216005.html
Copyright © 2020-2023  润新知