Linux上定时器的实现

Posted shiyicode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux上定时器的实现相关的知识,希望对你有一定的参考价值。

方法1. 使用sleep或者usleep

这种方法很简单,这里就不具体描述,它的缺点也很明确:精度不够,特别是在系统负载比较大时,会发生超时现象。

方法2. 使用信号量SIGALRM + alarm()

alarm也称为闹钟函数,alarm()用来设置在经过参数seconds指定的秒数后传送信号SIGALRM给目前的进程。如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回。要注意的是,一个进程只能有一个闹钟时间,如果在调用alarm之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替。
那么我们可以使用signal函数设定SIGALRM的处理函数,然后使用alarm定时发送SIGALRM来达到我们的目的。

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void timer(int sig)

    if(SIGALRM == sig)
    
        printf("timer\\n");
        alarm(1);
    
    return;


int main()

    signal(SIGALRM, timer);
    alarm(1);

    getchar();

    return 0;

这里只是简单的实现了一下,所以是无线循环定时,完善很容易。
这个方法很方便,实现也很简单,但是也有缺点,就是精度不能小于1秒。

方法3. select+多线程

原理很简单,利用select()方法的第5个参数,第一个参数设置为0,三个文件描述符集都设置为NULL,第5个参数为时间结构体,设置为我们想要定时的事件频率即可。

#include <iostream>
#include <pthread.h>
#include <functional>
#include <time.h>
#include <sys/select.h>
#include <unistd.h>

class Timer
public:
    Timer() = default;

    Timer(int sec, int usec, int count, const std::function<void()> &callback)
    : sec_(sec), usec_(usec), count_(count), callback_(callback)

    

    void startTimer()
        pthread_create(&thread_, NULL, work, this);
    

    void endTimer()
        //终止线程
        pthread_cancel(thread_);
        //回收线程资源
        pthread_join(thread_, NULL);
    

private:
    //解决类成员函数不能作为pthread_create函数参数的问题
    static void* work(void* timer)
        static_cast<Timer*>(timer)->workTimer();
    

    void workTimer()
        for(int i=0; i<count_; i++)
            struct timeval tempval;
            tempval.tv_sec = sec_;
            tempval.tv_usec = usec_;
            select(0, NULL, NULL, NULL, &tempval);
            callback_();
        
    

    int sec_;
    int usec_;
    int count_;
    std::function<void()> callback_;
    pthread_t thread_;
;

int main()

    Timer a(1,0,10,[]()std::cout<<"timer a"<<std::endl;);
    a.startTimer();
    Timer b(2,0,5,[]()std::cout<<"timer b"<<std::endl;);
    b.startTimer();

    getchar();
    return 0;

运行结果:

以上是关于Linux上定时器的实现的主要内容,如果未能解决你的问题,请参考以下文章

Linux上定时器的实现

Linux内核定时器

linux定时器的实现方法

《Linux内核设计与实现》读书笔记- 定时器和时间管理

linux 等待队列

Linux监控文件变化及主动上报实现