Linux/Unix下几种实现定时的方式总结
Posted Overboom
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux/Unix下几种实现定时的方式总结相关的知识,希望对你有一定的参考价值。
定时器Timer应用场景非常广泛,在Linux下,有以下几种方法:
1. 使用sleep()和usleep()
其中sleep精度是1秒,usleep精度是1微妙,具体代码就不写了。使用这种方法缺点比较明显,在Linux系统中,sleep类函数不能保证精度,尤其在系统负载比较大时,sleep一般都会有超时现象。
2. 使用信号量SIGALRM + alarm()
这种方式的精度能达到1秒,其中利用了*nix系统的信号量机制,首先注册信号量SIGALRM处理函数,调用alarm(),设置定时长度,代码如下:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
typedef void (*sighandler_t)(int);
typedef unsigned long int __uint64_t;
typedef __uint64_t uint64_t;
uint64_t GetCurrentTimeStamp()
{
struct timespec tp;
uint64_t timestamp = 0;
int ret = clock_gettime(CLOCK_MONOTONIC, &tp);
if (ret == 0) {
timestamp = tp.tv_sec * 1000 * 1000 * 1000 + tp.tv_nsec;
} else {
printf("gettime failed");
timestamp = 0;
}
return timestamp;
}
void someone_func_handler(int param)
{
printf("hello world\\n");
printf("%ld, %d\\n", GetCurrentTimeStamp(), __LINE__);
}
int main(void)
{
int i;
sighandler_t handler = someone_func_handler;
signal(SIGALRM, handler);
alarm(5);
printf("%ld, %d\\n", GetCurrentTimeStamp(), __LINE__);
for(i = 1; i < 10; i++)
{
printf("sleep %d ...\\n", i);
sleep(1);
}
return 0;
}
编译输出:
3. 使用select()
这种方法在看APUE神书时候看到的,方法比较冷门,通过使用select(),来设置定时器;原理利用select()方法的第5个参数,第一个参数设置为0,三个文件描述符集都设置为NULL,第5个参数为时间结构体,代码如下:
#include <sys/time.h>
#include <sys/select.h>
#include <time.h>
#include <stdio.h>
/*seconds: the seconds; mseconds: the micro seconds*/
void setTimer(int seconds, int mseconds)
{
struct timeval temp;
temp.tv_sec = seconds;
temp.tv_usec = mseconds;
select(0, NULL, NULL, NULL, &temp);
printf("timer\\n");
return ;
}
int main()
{
int i;
for(i = 0 ; i < 100; i++)
setTimer(1, 0);
return 0;
}
这种方法精度能够达到微妙级别,网上有很多基于select()的多线程定时器,说明select()稳定性还是非常好。
总结:如果对系统要求比较低,可以考虑使用简单的sleep(),毕竟一行代码就能解决;如果系统对精度要求比较高,则可以考虑RTC机制和select()机制。
以上是关于Linux/Unix下几种实现定时的方式总结的主要内容,如果未能解决你的问题,请参考以下文章