linux下的计时器

近来有读者或许会迷惑,在linux下开发时往往会遇到一些场景,例如:如何让程序运行特定的时间然后退出?如何在循环一定的时间后自动执行某段程序,例如在判断到小孩打开游戏,运行5分钟后自动执行退出脚本?这就涉及到中断和计时器的知识了。

通常在linux中我们可以使用以下两种计时器函数来完成代码

  1. alarm函数
    所需头文件 #include
    原型:
    unsigned int alarm(unsigned int seconds)

alarm函数给发送一个SIGALRM中断,由signal函数捕捉然后处理。
以下是配合signal函数

#include 
#include 
#include 
#include 

int flag = 0;
int main(void)
{
    /*lambda 表达式简单定义一个中断处理函数 */
    auto bb = [](int sig) -> void{printf("alarm!\n"); flag=1; return; };
    signal(SIGALRM, bb);  //注册捕获信号的函数,即 交由bb处理
    alarm(1);
    while (1)
    {
        if (flag == 1)
        {
            printf("hhh\n");
            return 0;
        }
    }
    return 0;
}

【参考:https://linuxhint.com/sigalar...
上面这个例子中是说,等待2秒以后自动结束循环,这一功能的实现。但是alarm函数一个进程只能有一个定(计)时器,这对于多线程和异步程序来说特别不友好,同时使用会有冲突和安全问题。
在bb函数里增加alarm(k)可以实现重复发送的功能。但是每一个alarm发出的SIGALRM中断调用的都是bb函数,在不同的线程里是不会做区分的。而且只能以秒为单位,局限比较大。

  1. setitimer()
    setitimer()为Linux的API,并非C语言的Standard Library,setitimer()有两个功能,一是指定一段时间后,才执行某个function,二是每间格一段时间就执行某个function,以下程序demo如何使用setitimer()。
    定义:

     #include 
     int setitimer( int which,
                 const struct itimerval *value,   
                 struct itimerval *ovalue );

    ITIMER_REAL:以系统真实的时间来计算,它送出SIGALRM信号。
    ITIMER_VIRTUAL:以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
    ITIMER_PROF:以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。
    linux下的计时器_第1张图片

下面是实例

#include 
#include 
#include 

int main(void)
{
    auto bb = [](int signum) -> void{printf("alarm!\n"); return;};
    signal(SIGALRM, bb);
    struct itimerval new_one, old_one; 
    /*******  通过new_one 设置 **********/
    /* tv_sec + tv_usec* 1/1e6 = 重复的间隔时间 it_interval 为0时候则一直延时*/ 
    new_one.it_interval.tv_sec = 0; 
    new_one.it_interval.tv_usec = 3e5;  // 取值 < 1e6
     /* 同理,初始执行时间*/
    new_one.it_value.tv_sec = 1;
    new_one.it_value.tv_usec = 0; // 取值 < 1e6

    setitimer(ITIMER_REAL, &new_one, &old_one); // old_one 不用赋值
    
    for(;;);
    printf("1122\n");
    return 0;
}

后记:有其他实现方式吗,有没有什么注意事项?底层原理是什么?以后有机会继续挖掘。

你可能感兴趣的:(linuxc++c)