一. 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下没有现成的毫秒级延时,这里我们可以自己简单写一个:
#include <unistd.h>
void msleep(unsigned long ms)
{
struct timeval tv;
tv.tv_sec = ms/1000;
tv.tv_usec = (ms%1000)*1000;
select(0, NULL, NULL, NULL, &tv);
}
二. signal与alarm()
使用signal函数设定SIGALRM的处理函数,然后使用alarm()定时发送SIGALRM来实现。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int alarm_flag=1;
void timer(int sig)
{
if(SIGALRM == sig)
{
alarm_flag = 1;
}
return;
}
int main()
{
signal(SIGALRM, timer);
while( alrm_flag )
{
alarm_flag = 0;
printf("hello\n");
alarm(5);
}
return 0;
}
#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;
};
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
void timer_s(unsigned long s, unsigned long us)
{
struct timeval tv;
tv.tv_sec = s;
tv.tv_usec = us;
select(0, NULL, NULL, NULL, &tv);
}
int main()
{
while(1)
{
printf("hello\n");
timer_s(3, 0);
}
return 0;
}
四. 一些总结
大家根据自己需求选择,这是在网上扒下来的一张图,原文链接如下:
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
版权归原作者 奶香闪电 所有, 如有侵权,请联系我们删除。