Linux实现定时器

来源:互联网 发布:mac怎么卸载adobe 编辑:程序博客网 时间:2024/05/29 13:57

定时器实现的方式有很多。
1.alarm产生一个超时信号,在信号处理函数中再次alarm一下。
2.libevent和nginx的做法是用epoll/poll的超时时间来做,不过这需要额外的二叉堆/红黑树结构来维护。
3.muduo中使用了一种新的方式timerfd_*非常方便,使用的时候像IO事件一样直接扔进reactor中即可。

下面是代码:

#include <sys/timerfd.h>  #include <sys/epoll.h>#include <unistd.h>#include <stdint.h>#include <iostream>using namespace std;const int EPOLL_SIZE = 10;int main(int argc, char* argv[]){    int tfd, epfd, nfds;    struct epoll_event event;    struct epoll_event events[EPOLL_SIZE];    //创建timerfd, CLOCK_REALTIME为绝对时间,TFD_NONBLOCK为非阻塞    tfd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK);      if (tfd < 0)    {    cerr << "timerfd_create error!" << endl;    return -1;    }        struct timespec startTime, intervalTime;    startTime.tv_sec = 0;        startTime.tv_nsec = 1;                                //相当于立即到达超时时间    intervalTime.tv_sec = 3;                             //首次超时后,每三秒超时一次    intervalTime.tv_nsec = 0;    struct itimerspec newValue;    newValue.it_value = startTime;    newValue.it_interval = intervalTime;    //设置超时时间,且为相对时间    if (timerfd_settime(tfd, 0, &newValue, NULL) < 0)    {    cerr << "timerfd_settime error!" << endl;    return -1;    }    //用epoll来监听描述符    epfd = epoll_create(EPOLL_SIZE);    if (epfd < 0)    {    cerr << "epoll_create error!" << endl;    return -1;    }    event.data.fd = tfd;    event.events = EPOLLIN;    if (epoll_ctl(epfd, EPOLL_CTL_ADD, tfd, &event) < 0)    {    cerr << "epoll_ctl error!" << endl;    return -1;    }    uint64_t count = 0;    while (1)    {    //非阻塞等待    nfds = epoll_wait(epfd, events, EPOLL_SIZE, 0);    if (nfds == 0) continue;    for (int i = 0; i < nfds; i++)    {        if (events[i].events & EPOLLIN)        {        uint64_t data;        read(events[i].data.fd, &data, sizeof(uint64_t));        count += data;        cout << "read: " << data << ", timer count: " << count << endl;        }    }    }    return 0;}

参考:
http://www.jianshu.com/p/66b3c75cae81

原创粉丝点击