zoukankan      html  css  js  c++  java
  • linux几种定时函数的使用

    Linux定时函数介绍:

      在程序开发过程中,我们时不时要用到一些定时器,通常如果时间精度要求不高,可以使用sleep,uslepp函数让进程睡眠一段时间来实现定时,

    前者单位为秒(s),后者为微妙(us);但有时候我们又不想让进程睡眠阻塞在哪儿,我们需要进程正常执行,当到达规定的时间时再去执行相应的操作,

    在linux下面我们一般使用alarm函数跟setitimer函数来实现定时功能;

    下面对这两个函数进行详细分析:

    (1)alarm函数

      alarm也称为闹钟函数,它可以在进程中设置一个定时器,当定时器指定的时间到时,它向进程发送SIGALRM信号;

    alarm函数原型如下:

    1 unsigned int alarm(unsigned int seconds);
    2 
    3 //seconds 为指定的秒数
    返回值:
    成功:如果调用此alarm()前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。
    出错:-1
    下面是alarm()函数的简单例子:
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <unistd.h>
     4 #include <signal.h>
     5 
     6 void func()
     7 {
     8     printf("this is func
    ");
     9 }
    10 
    11 int main()
    12 {
    13 
    14     signal(SIGALRM, func); //2s后要执行的函数
    15     alarm(2);//设置定时2s
    16 
    17     while (1);
    18 
    19     return 0;
    20 }

    (2)setitimer()函数

      在linux下如果对定时要求不太精确的话,使用alarm()和signal()就行了,但是如果想要实现精度较高的定时功能的话,就要使用setitimer函数。

      setitimer()为Linux的API,并非C语言的Standard Library,setitimer()有两个功能,一是指定一段时间后,才执行某个function,二是每间格一段时间就执行某个function;

      Linux为每个任务安排了3个内部定时器:

    ITIMER_REAL:实时定时器,不管进程在何种模式下运行(甚至在进程被挂起时),它总在计数。定时到达,向进程发送SIGALRM信号。

    ITIMER_VIRTUAL:这个不是实时定时器,当进程在用户模式(即程序执行时)计算进程执行的时间。定时到达后向该进程发送SIGVTALRM信号。 

    ITIMER_PROF:进程在用户模式(即程序执行时)和核心模式(即进程调度用时)均计数。定时到达产生SIGPROF信号。ITIMER_PROF记录的时间比ITIMER_VIRTUAL多了进程调度所花的时间。

    定时器在初始化是,被赋予一个初始值,随时间递减,递减至0后发出信号,同时恢复初始值。在任务中,我们可以一种或者全部三种定时器,但同一时刻同一类型的定时器只能使用一个。

    setitimer函数原型如下:

     1  #include <sys/time.h>
     2 
     3        int setitimer(int which, const struct itimerval *new_value,
     4                      struct itimerval *old_value);
     5 
     6  Timer values are defined by the following structures:
     7 
     8            struct itimerval {
     9                struct timeval it_interval; /* next value */
    10                struct timeval it_value;    /* current value */
    11            };
    12 
    13            struct timeval {
    14                time_t      tv_sec;         /* seconds */
    15                suseconds_t tv_usec;        /* microseconds */
    16            };

      it_interval用来指定每隔多长时间执行任务, it_value用来保存当前时间离执行任务还有多长时间。比如说, 你指定it_interval为2秒(微秒为0),开始的时候我们把it_value的时间也设定为2秒(微秒为0),当过了一秒, it_value就减少一个为1, 再过1秒,则it_value又减少1,变为0,这个时候发出信号(告诉用户时间到了,可以执行任务了),并且系统自动把it_value的时间重置为 it_interval的值,即2秒,再重新计数

    下面是setitimer简单实例:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <signal.h>
     5 #include <sys/time.h>
     6 
     7 void test_func()
     8 {
     9     static count = 0;
    10 
    11     printf("count is %d
    ", count++);
    12 }
    13 
    14 void init_sigaction()
    15 {
    16     struct sigaction act;
    17           
    18     act.sa_handler = test_func; //设置处理信号的函数
    19     act.sa_flags  = 0;
    20 
    21     sigemptyset(&act.sa_mask);
    22     sigaction(SIGPROF, &act, NULL);//时间到发送SIGROF信号
    23 }
    24 
    25 void init_time()
    26 {
    27     struct itimerval val;
    28          
    29     val.it_value.tv_sec = 1; //1秒后启用定时器
    30     val.it_value.tv_usec = 0;
    31 
    32     val.it_interval = val.it_value; //定时器间隔为1s
    33 
    34     setitimer(ITIMER_PROF, &val, NULL);
    35 }
    36 
    37 int main(int argc, char **argv)
    38 {
    39 
    40     init_sigaction();
    41     init_time();
    42 
    43     while(1);
    44 
    45     return 0;
    46 }

    可以看出每个一秒输出一个count的值:

    下面是运行结果:

    [root@localhost 5th]# ./test
    count is 0
    count is 1
    count is 2
    count is 3
    count is 4
    count is 5
    count is 6
    count is 7
    count is 8
    count is 9

  • 相关阅读:
    业务决定功能,功能决定技术
    类的设计问题
    鲁棒图的三元素:抽象对象,实体对象和控制对象
    swift 命名空间实现的设计思考:extension YKKit where Base == String
    iOS keychain注解
    学科基本结构理论-布鲁纳学习理论
    软件框架的理解
    数据库管理系统-可扩展的功能组件
    SQLite权威指南
    应用程序员眼中的数据库管理系统:API+数据库语言
  • 原文地址:https://www.cnblogs.com/wenqiang/p/5525261.html
Copyright © 2011-2022 走看看