• Linux 定时器使用


    Linux 下可以使用 alarm 函数或 setitimer 函数设置一个定时器。alarm 的定时器是以 秒计时的,setitimer 的定时器可以精确到 微秒

    一、alarm 定时器

    alarm 可以在进程中设置一个定时器,当定时器指定的时间到时,它向进程发送SIGALRM信号。可以设置忽略或者不捕获此信号,如果采用默认方式其动作是终止调用该alarm函数的进程。

    #include <unistd.h>
    
    unsigned int alarm(unsigned int seconds);
    
    • 1
    • 2
    • 3

    seconds:指定秒数
    成功:如果调用此alarm() 前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0
    失败:-1

    示例

    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h>
    
    void sigHandFun(int signum)
    {
    	printf("3秒时间到...\n");
    }
    
    int main(int argc, char const *argv[])
    {
    	if (SIG_ERR == signal(SIGALRM, sigHandFun)) {
    		perror("signal");
    		return -1;
    	}
    
    	alarm(3);
    	printf("启动定时器,计时3秒...\n");
    
    	pause(); //SIGALRM 信号处理函数返回后,pause 立即返回
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    二、setitimer 定时器

    #include <sys/time.h>
    
    int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
    
    • 1
    • 2
    • 3

    which: 为定时器类型,setitimer支持3种类型的定时器:

    • ITIMER_REAL: 定时器值实时递减,发生的信号为 SIGALRM (常用)
    • ITIMER_VIRTUAL: 进程执行时递减定时器的值,发送的信号为 SIGVTALRM
    • ITIMER_PROF: 进程和系统执行时都递减定时器的值,发送的信号为 SIGPROF

    new_value: 设置定时时长,和指定 多长时间后启动定时器
    old_value:记录上一次的定时设置,不用 传NULL
    成功返回 0,否则返回 -1

    struct itimerval {
    		struct timeval it_interval; /* 定时时长 */
    		struct timeval it_value;    /* 启动时间 */
    };
    
    struct timeval {
    		time_t      tv_sec;         /* 秒 */
    		suseconds_t tv_usec;        /* 微秒 */
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    示例:

    #include <stdio.h>
    #include <signal.h>
    #include <unistd.h>
    #include <sys/time.h>
    
    void sigHandFun(int signum)
    {
    	static int n = 0;
    
    	n++;
    	if (2000 == n) {
    		printf("1秒时间到...\n");
    	}
    }
    
    int main(int argc, char const *argv[])
    {
    	struct itimerval itv;
    
    	//信号处理
    	if (SIG_ERR == signal(SIGALRM, sigHandFun)) {
    		perror("signal");
    		return -1;
    	}
    
    	//设置定时时长: 0.5ms
    	itv.it_interval.tv_sec  = 0;
    	itv.it_interval.tv_usec = 500;
    
    	//设置启动时间: 1秒后启动
    	itv.it_value.tv_sec  = 1;
    	itv.it_value.tv_usec = 0;
    
    	//设置定时器
    	if (-1 == setitimer(ITIMER_REAL, &itv, NULL)) {
    		perror("setitimer");
    		return -1;
    	}
    
    	while(1);	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    JavaScript基础
    代码无法输出操作值,如何解决?(语言-c语言)
    Linux下Cmake安装或版本更新
    『现学现忘』Git分支 — 39、Git中分支与对象的关系
    Vue3+TypeScript+Element Plus前端项目构建入门
    2022年11月19日(星期六):骑行甸尾
    版本管理的使用
    HTML 笔记 表格
    Redis入门到实战(四、原理篇)RESP协议
    Kotlin协程-select基础
  • 原文地址:https://blog.csdn.net/weixin_54178481/article/details/125626004