zoukankan      html  css  js  c++  java
  • 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)

          {

              

          }

    }

  • 相关阅读:
    HDU 1261 字串数(排列组合)
    Codeforces 488C Fight the Monster
    HDU 1237 简单计算器
    POJ 2240 Arbitrage
    POJ 3660 Cow Contest
    POJ 1052 MPI Maelstrom
    POJ 3259 Wormholes
    POJ 3268 Silver Cow Party
    Codesforces 485D Maximum Value
    POJ 2253 Frogger(最短路)
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9216005.html
Copyright © 2011-2022 走看看