当前位置:   article > 正文

linux下实现定时器的三种简单方式_linux 定时器

linux 定时器

目录

一. sleep()和usleep()

1.sleep()

2.usleep()

3.毫秒级延时

二. signal与alarm()

三. select

四. 一些总结


一. sleep()和usleep()

        优点是简单便捷,直接调用即可,但是缺点也很明显,精度不够,特别是在系统负载比较大时,会发生超时现象。

1.sleep()

#include <unistd.h>

unsigned int sleep(unsigned int   seconds);

功能:执行挂起指定的秒数

        sleep()只能精确到秒级上。sleep()非系统调用,sleep()是在库函数中实现的,它是通过alarm()来设定报警时间,使用sigsuspend()将进程挂起在信号SIGALARM上。sleep()会令目前的进程暂停,直到达到参数seconds 所指定的时间,或是被信号所中断。

2.usleep()

#include <unistd.h>

void usleep(int     micro_seconds);

功能:把进程挂起一段时间,单位是微秒(百万分之一)

        除了时间单位为微秒以外,在使用上与sleep()差不多。但实现是不同的,sleep是用alarm实现的,所以时间单位为s ,而usleep的时间单位为us,肯定不是由alarm实现的,所以说它们的实现不同,但都是linux用的,而window下不能用,因为都是sleep和usleep都是在unistd.h下定义的。

        一般情况下,延迟时间数量级是秒的时候,尽可能使用sleep()函数。如果延迟时间为几十毫秒(1ms = 1000us),或者更小,尽可能使用usleep()函数。这样才能最佳的利用CPU时间。

3.毫秒级延时

        因为linux下没有现成的毫秒级延时,这里我们可以自己简单写一个:

  1. #include <unistd.h>
  2. void msleep(unsigned long ms)
  3. {
  4. struct timeval tv;
  5. tv.tv_sec = ms/1000;
  6. tv.tv_usec = (ms%1000)*1000;
  7. select(0, NULL, NULL, NULL, &tv);
  8. }

二. signal与alarm()

        使用signal函数设定SIGALRM的处理函数,然后使用alarm()定时发送SIGALRM来实现。  

  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include <unistd.h>
  4. int alarm_flag=1;
  5. void timer(int sig)
  6. {
  7. if(SIGALRM == sig)
  8. {
  9. alarm_flag = 1;
  10. }
  11. return;
  12. }
  13. int main()
  14. {
  15. signal(SIGALRM, timer);
  16. while( alrm_flag )
  17. {
  18. alarm_flag = 0;
  19. printf("hello\n");
  20. alarm(5);
  21. }
  22. return 0;
  23. }

#include <unistd.h>

unsigned int alarm(unsigned int         seconds);        

功能:设置信号传送闹钟

        alarm()也称为闹钟函数,alarm()函数的主要功能是设置信号传送闹钟,即⽤来设置信号SIGALRM 在经过参数seconds 秒数后发送给⽬前的进程。如果未设置信号SIGALARM 的处理函数,那么alarm()默认处理终⽌进程。如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回。

        PS:一个进程只能有一个闹钟时间,如果在调用alarm之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替。

三. select

#include <sys/select.h>

#include <sys/time.h>

#include <sys/types.h>

#include <unistd.h>

int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval * timeout);

功能:用来等待文件描述词状态的改变。参数n代表最大的文件描述词加1,参数readfds、writefds 和exceptfds称为描述词组,是用来回传该描述词的读,写或例外的状况。

         这里就不详细介绍select函数的参数及功能了,大家感兴趣可以自行查阅。这里要实现定时器的话,把第一个参数设置为0,中间三个文件描述符集都设置为NULL,第五个参数为时间结构体,我们主要就是使用参数,把它设置为我们想要定时的频率就好。

        timeout为结构timeval,用来设置select()的等待时间,其结构定义如下:

struct timeval

{

        time_t        tv_sec;

        time_t        tv_usec;
};

  1. #include <sys/select.h>
  2. #include <sys/time.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5. void timer_s(unsigned long s, unsigned long us)
  6. {
  7. struct timeval tv;
  8. tv.tv_sec = s;
  9. tv.tv_usec = us;
  10. select(0, NULL, NULL, NULL, &tv);
  11. }
  12. int main()
  13. {
  14. while(1)
  15. {
  16. printf("hello\n");
  17. timer_s(3, 0);
  18. }
  19. return 0;
  20. }

四. 一些总结

        大家根据自己需求选择,这是在网上扒下来的一张图,原文链接如下:

Linux中的sleep、usleep、nanosleep、poll和select不同的sleep方式https://mp.weixin.qq.com/s?src=11×tamp=1680196399&ver=4438&signature=LzDVJT7uLU7DuxA6qxK8Sm4FqjJw8G347mhB56nkDIb5R2XQsifqz-NFi1nmisdVYxrrRNgLVKIJqjN4koJ59oTtTBWunbaWVMV7u6dNydmBRf-DA9aR6yVNKkbJF*oI&new=1

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/225071
推荐阅读
相关标签
  

闽ICP备14008679号