timerfd

2020-12-30  本文已影响0人  wayyyy

Linux内核于内核2.6之后提供了一种创建定时器的方法,那就是Linux特有的timerfd文件描述符(一切皆文件),这也意味着可以用多路复用来监听并读取。该接口共有3个API。

配合使用epoll监听定时器
#include <time.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <assert.h>
using namespace std;

const int MAXNUM = 20;

int main(int argc, char *argv[])
{
    struct itimerspec new_value;
    struct timespec now;
    uint64_t exp;
    ssize_t s;

    int ret = clock_gettime(CLOCK_REALTIME, &now);//获取时钟时间
    assert(ret != -1);

    new_value.it_value.tv_sec = 5; //第一次到期的时间
    new_value.it_value.tv_nsec = now.tv_nsec; 

    new_value.it_interval.tv_sec = 1;      //之后每次到期的时间间隔
    new_value.it_interval.tv_nsec = 0;

    int timefd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK); // 构建了一个定时器
    assert(timefd != -1);

    ret = timerfd_settime(timefd, 0, &new_value, NULL);//启动定时器
    assert(ret != -1);

    cout << "timer started" << endl; // 定时器开启啦!


    int epollfd = epoll_create(1);  //创建epoll实例对象

    struct epoll_event ev;
    struct epoll_event events[MAXNUM];
    ev.data.fd = timefd;
    ev.events = EPOLLIN | EPOLLET;
    epoll_ctl(epollfd, EPOLL_CTL_ADD, timefd, &ev); //添加到epoll事件集合

    for (; ;) 
    {
        int num = epoll_wait(epollfd, events, MAXNUM, 0);
        assert(num >= 0);

        for (int i = 0; i < num; i++) 
        {
            if (events[i].events & EPOLLIN) 
            {
                //....处理其他事件
                if (events[i].data.fd == timefd) 
                {
                    s = read(events[i].data.fd, &exp, sizeof(uint64_t)); //需要读出uint64_t大小, 不然会发生错误
                    assert(s == sizeof(uint64_t));
                    cout << "here is timer" << endl;
                }
            }
        }
    }

    close(timefd);
    close(epollfd);

    return 0;
}

参考资料
1.https://blog.csdn.net/weixin_36888577/article/details/81570793

上一篇下一篇

猜你喜欢

热点阅读