zoukankan      html  css  js  c++  java
  • fd定时器--timerfd学习

    定时器

    可以用系统定时器信号SIGALARM

    最近工作需要于是又发现了一个新玩意timerfd配合epoll使用。

    man 手册看一下

    TIMERFD_CREATE(2)                         Linux Programmer's Manual                         TIMERFD_CREATE(2)
    
    NAME
           timerfd_create, timerfd_settime, timerfd_gettime - timers that notify via file descriptors
    
    SYNOPSIS
           #include <sys/timerfd.h>
    
           int timerfd_create(int clockid, int flags);
    
           int timerfd_settime(int fd, int flags,
                               const struct itimerspec *new_value,
                               struct itimerspec *old_value);
    
           int timerfd_gettime(int fd, struct itimerspec *curr_value);
    
    DESCRIPTION
           These  system  calls  create and operate on a timer that delivers timer expiration notifications via a
           file descriptor.  They provide an alternative to the use of setitimer(2) or timer_create(2), with  the
           advantage that the file descriptor may be monitored by select(2), poll(2), and epoll(7).
    
           The  use of these three system calls is analogous to the use of timer_create(2), timer_settime(2), and
           timer_gettime(2).  (There is no analog of timer_getoverrun(2), since that functionality is provided by
           read(2), as described below.)

    这是一个专门针对fd的定时器,通过fd可以读取定时数据(定时时间到了就会有数据回来,否则阻塞(阻塞模式))。

    结合epoll使用先弄个epoll出来

    /* init epoll */
    int epollInit(){
        int epFd = epoll_create(EPOLL_SIZE);
        if (epFd < 0){
            perror("epoll create");
            return -1;
        }
        return epFd;
    }

    然后在弄个timerfd,并把它加入到epoll 事件中

    int TimerFdInit(int epFd)
    {
        struct itimerspec new_value;
        /*init time*/
        new_value.it_value.tv_sec = 1;
        new_value.it_value.tv_nsec = 0;
        /*time interval*/
        new_value.it_interval.tv_sec = 1;
        new_value.it_interval.tv_nsec = 0;
    
        int timerFd = timerfd_create(CLOCK_MONOTONIC, 0);
        if (timerFd < 0) {
            cerr<<strerror(errno)<<endl;
            return -1;
        }
    
        int ret = timerfd_settime(timerFd, 0, &new_value, NULL);
        if (ret < 0) {
            cerr<<strerror(errno)<<endl;
            close(timerFd);
            return -1;
        }
        /* add to epoll */
        struct epoll_event ev;
        ev.events = EPOLLIN | EPOLLHUP | EPOLLRDHUP;
        ev.data.fd = timerFd;
        epoll_ctl(epFd, EPOLL_CTL_ADD, timerFd, &ev);
        return timerFd;
    }

    接下来就去epoll_wait循环等待这个定时器的数据

    int epollHandle(int epFd, int timerFd)
    {
        struct epoll_event epEvents[EPOLL_SIZE] = {};
        int timeOut = -1;
        uint64_t totalExp = 0;
        while (1)
        {
            //blocked
            int eventNum = epoll_wait(epFd, epEvents, EPOLL_SIZE, timeOut);
            if(eventNum < 0) {
                perror("epoll failure");
                return -1;
            }
    
            //handle epEvents
            for(int i = 0; i < eventNum; ++i) {
                int tmpFd = epEvents[i].data.fd;
                if(epEvents[i].events & EPOLLIN) {
                    if (timerFd == tmpFd) {
                        /*handle timerFd*/
                        uint64_t tmpExp = 0;
                        /*must read*/
                        read(timerFd, &tmpExp, sizeof(uint64_t));
                        totalExp += tmpExp;
                        cout<<"timer count "<<totalExp<<endl;
                    }
                  }
               }
            }
        return 0;
    }
  • 相关阅读:
    (转)tomcat 安全配置文档
    (转)nginx 安全配置文档
    (转)scipy详解
    (转)matplotlib实战
    (转)Python3的四舍五入round()函数坑爹?不,更科学!
    (转)p解决 java.util.prefs.BackingStoreException 报错问题
    (转)asyncio --- 异步 I/O
    (转)pycharm快捷键、常用设置、配置管理
    (转)db2top详解
    (转)Db2 数据库常见堵塞问题分析和处理
  • 原文地址:https://www.cnblogs.com/tid-think/p/10779026.html
Copyright © 2011-2022 走看看