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下几种实现定时的方式总结的主要内容,如果未能解决你的问题,请参考以下文章

LInux下几种定时器的比较和使用

Vi命令下几种容易混淆的插入方式

PHP实现定时任务的几种方式

Java 定时任务的几种实现方式

linux下几种常见安装方式

Linux下几种反弹Shell方法的总结---持续更新