• 定时器的使用和线程安全


           在linux下如果对定时要求不太精确的话,使用alarm()和signal()就行了;

           但是如果想要实现精度较高的定时功能的话,就要使用setitimer函数。

    核心api:

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

    调用成功返回0,否则返回-1;

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

    ITIMER_REAL: 以系统真实的时间来计算,它送出SIGALRM信号。

    ITIMER_VIRTUAL: -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。

    ITIMER_PROF: 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。

    第一个参数which指定定时器类型(上面三种之一);第二个参数是结构itimerval的一个实例;第三个参数可不做处理。

    1. //下面这两个是八股,要用计时器setitimer()就必须先配好
    2. struct itimerval {
    3. struct timeval it_interval; //it_interval指定间隔时间
    4. struct timeval it_value; //it_value指定初始定时时间
    5. };
    6. struct timeval {
    7. long tv_sec; //
    8. long tv_usec; //微妙
    9. };
    10. //如果只指定it_value,就是实现一次定时
    11. //如果it_value和it_interval都指定,则超时后,系统会重新初始化it_value为it_interval,实现重复定时
    12. //如果两者都清零,则会清除定时器
    13. //tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us = 1000ms
    14. //ovalue用来保存先前的值,常设为NULL

    例子:

    1. #include <stdio.h>
    2. #include <sys/time.h>
    3. #include <unistd.h>
    4. #include <stdlib.h>
    5. #include <string.h>
    6. #include <signal.h>
    7. void call_back(int sig)
    8. {
    9. static int count = 1;
    10. printf("call_back : %d
    11. ", count++);
    12. }
    13. int main(void)
    14. {
    15. signal(SIGALRM, call_back);
    16. struct itimerval new_value;
    17. memset(&new_value, 0, sizeof(new_value));
    18. new_value.it_interval.tv_sec = 1; //设置再次定时时间为1S
    19. new_value.it_interval.tv_usec = 0;
    20. new_value.it_value.tv_sec = 2; //设置首次定时时间为2S
    21. new_value.it_value.tv_usec = 0;
    22. int ret = setitimer(ITIMER_REAL, &new_value, NULL);
    23. if (0 != ret)
    24. {
    25. perror("setitimer");
    26. exit(-1);
    27. }
    28. getchar();
    29. return 0;
    30. }

    线程安全:

    定时器死了,死循环就停不了,线程退出不了,还有就是主程序退出时,你的这个线程怎么安全退出。

    还有就是实际的延时的问题,线程实际的输出时间比设定的长或者短。 

    这里要特别注意一下sleep()和大写的Sleep()还有usleep()的时间单位是不同的,秒,毫秒和微秒

  • 相关阅读:
    upload-labs靶场详解
    Go语学习笔记 - gorm使用 - 数据库配置、表新增 Web框架Gin(七)
    【Try Hack Me】内网专项---Wreath
    Linux入门第三讲(完结)
    超神之路 数据结构 1 —— 关于数组的基本认识
    六年 Android 开发是如何从15K涨到30K?
    Ubuntu 20.04安装Docker
    y45.第三章 Kubernetes从入门到精通 -- k8s中运行web服务(十八)
    1 认识 Android
    智慧餐饮系统架构的设计与实现
  • 原文地址:https://blog.csdn.net/weixin_51431342/article/details/127903381