zoukankan      html  css  js  c++  java
  • Unix环境编程之定时、信号与中断

    在linux下实现精度较高的定时功能,需要用到setitimer 和 getitimer函数。

    函数原型:

    #include <sys/time.h>
    int getitimer(int which, struct itimerval *curr_value);
    int setitimer(int which, const struct itimerval *new_value,
                         struct itimerval *old_value);

    · 函数getitimer()把指定的定时器类型( ITIMER_REAL,  ITIMER_VIRTUAL,  或 ITIMER_PROF中的一个)写入curr_value指向的结构。

    it_value设置为定时器剩余时间(若定时器关闭则为0)。类似的,it_interval设置为复位时间。

    分析形参:

    1. int which

      which为定时器类型,setitimer支持3种类型的定时器:
    ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。
    ITIMER_VIRTUAL: -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
    ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。
     
    2. const struct itimerval *value
      value 是一个指向itimerval类型的指针,介绍如下
     
    struct itimerval 
    {
        struct timeval it_interval;//next value
        struct timeval it_value;//current value
    };

    timeval也是一个数据类型:

    struct timeval 
    {
        long tv_sec;
        long tv_usec;
    };

      it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;两者都清零,则会清除定时器。tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先。

    3. struct itimerval *ovalue

      ovalue用来保存先前的值,通常设置为NULL。

    每次定时循环结束会产生中断,通常会用到signal函数捕捉处理,原型为:

    #include<signal.h>
    void  (* signal(int sig, void (*func) (int)) ) (int);

       signal()是一个系统调用,常用来设定某个信号(sig)的处理方法(func):

    信号类型(sig)

    (1) 与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。

    (2) 与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。

    (3) 与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。

    (4) 与执行系统调用时遇到非预测错误条件相关的信号。如执行一个并不存在的系统调用。

    (5) 在用户态下的进程发出的信号。如进程调用系统调用kill向其他进程发送信号。

    (6) 与终端交互相关的信号。如用户关闭一个终端,或按下break键等情况。

    (7) 跟踪进程执行的信号。

    下列宏常量表达式指定了标准的信号值:

    Marcro Signal
    SIGABRT 异常终止,如调用abort().
    SIGFPE 如除0或操作结果溢出(不一定是浮点操作).
    SIGILL 非法指令或无效的函数镜像,通常由于代码错误或执行数据引起.
    SIGINT 交互式中断信号,通常由用户产生.
    SIGSEGV 段冲突.访问非法存储空间时产生.
    SIGTERM 发给本程序的中止信号.
     
     
     
     
     
     
     
     
     
     
     
     
    处理方法(func)有三种,分别是:
      默认处理(SIG_DFL), 信号以其默认指定的行为进行处理。
      忽略信号(SIG_IGN), 信号被忽略而且程序会继续往下执行,即使没有任何意义。
      函数处理,以用户指定的函数来处理信号。
     
    仅看原型比较抽象,举个例子就知道了:
       
    #include<stdio.h>
    #include<sys/time.h>
    #include<signal.h>
    
    
    void response(void);
    int main()
    {
        struct itimerval my_timer;
        long n_sec, n_usec;
        my_timer.it_interval.tv_sec = 0;
        my_timer.it_interval.tv_usec = 300*1000;//300ms
        my_timer.it_value.tv_sec = 2;   //2s
        my_timer.it_value.tv_usec = 0;
    
        setitimer(ITIMER_REAL, &my_timer, NULL);
        
        signal(SIGALRM,(__sighandler_t)&response);
        while(1)
            ;
        return 0;
    }
    
    void response(void)
    {
        printf("Receive signal!!
    ");
    }

    上述代码片段将定时器初始值设为2s,循环值为300ms,则当setitimer函数执行以后2s产生SIGALRM中断,由signal函数指定中断处理函数为response();

    2s之后,每隔300ms产生一次SIGALRM中断。

    参考文章:
    http://www.uml.org.cn/c%2B%2B/200812083.asp
     

     
  • 相关阅读:
    Golang——面向对象
    Golang——排序算法
    python常用设计模式
    Golang基础——数据类型:指针
    Golang基础——数据类型:结构体
    Golang基础——数据类型:map
    css盒子模型
    css选择器以及样式优先级
    Android中finish()方法
    架构漫谈(二)认识概念是理解架构的基础
  • 原文地址:https://www.cnblogs.com/pannengzhi/p/4340729.html
Copyright © 2011-2022 走看看