1、概述

timerfd是Linux为用户程序提供的一个定时器接口。这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,所以能够被用于select/poll的应用场景。timerfd是linux内核2.6.25版本中加入的借口。
      timerfd、eventfd、signalfd配合epoll使用,可以构造出一个零轮询的程序,但程序没有处理的事件时,程序是被阻塞的。这样的话在某些移动设备上程序更省电。

2、函数接口

(1) 第一个系统调用, 该系统调用创建一个新的定时器对象 :

#include <sys/timerfd.h>
int timerfd_create(int clockid, int flags);
//成功返回一个指代该对象的文件描述符, 失败返回-1及errno
  • 参数 clockid 可以设置为 CLOCK_REALTIME 和 CLOCK_MONOTONIC

 CLOCK_REALTIME:可设定的系统级实时时钟,相对时间,从1970.1.1到目前的时间。更改系统时间会更改获取的值。也就是说,它以系统时间为坐标。

CLOCK_MONOTONIC:不可设定的恒定态时钟,与CLOCK_REALTIME相反,它是以绝对时间为准,获取的时间为系统重启到现在的时间,更改系统时间对齐没有影响。

  • 参数flags, 支持 TFD_CLOEXEC 和 TFD_NONBLOCK 和 0

TFD_CLOEXEC 为新的文件描述符设置运行时关闭标志 (FD_CLOEXEC)
  TFD_NONBLOCK 为底层的打开文件描述符设置 O_NONBLOCK 标志, 随后的读操作将是非阻塞的, 这与调用 fcntl 效果相同

(2) 第二个系统调用, 可以启动或停止由文件描述符 fd 所指代的定时器

int timerfd_settime(int fd, int flags, const struct itimerspec* new_value, struct itimerspec* old_value);
//成功返回0, 失败返回-1和 errno
  • 参数flags 的值可以是 0 (相对时间), 可以是 TFD_TIMER_ABSTIME (绝对时间)
  • 参数new_value、old_value都是struct itimerspec* 类型
struct itimerspec
{struct timespec it_interval;   //间隔时间struct timespec it_value;      //设置启动时间
};struct timespec
{time_t tv_sec;    //秒long tv_nsec;    //纳秒
};

(3) 第三个系统调用, 返回文件描述符 fd 所标识定时器的间隔及剩余时间

int timerfd_gettime(int fd, struct itimerspec *curr_value);
//成功返回0, 失败返回-1和errno

(4)获取时钟的值

#include <time.h>
int clock_gettime(clockid_t clk_id, struct timespect *tp);

3、使用epoll监听定时器事件

使用方法和socketfd类似,利用timerfd_create创建定时器事件,通过timerfd_settime设置启动时间和时间间隔,然后使用epoll_ctl加入监听队列。

#include <sys/timerfd.h>
#include <iostream>
#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 = now.tv_sec+3; //启动后3秒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);//如果创建相对时间事件,且 timerfd_settime  第二参数设置0,则不需要clock_gettime获取基准时间ret = timerfd_settime(timefd, TFD_TIMER_ABSTIME, &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, -1);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;
}

Linux环境SOCKET编程5:定时器接口timerfd相关推荐

  1. Linux环境SOCKET编程3:压力测试

    测试方法:使用epoll实现一个通用的服务器压力测试程序. 测试代码: #include <stdlib.h> #include <stdio.h> #include < ...

  2. Linux环境SOCKET编程2:epoll分析

    我们通过实现分析知道LT模式下epoll_wait被唤醒可以通过两种方式,而ET模式只能通过一种方式.所以ET模式下能被唤醒的情况,LT模式下一定也能被唤醒.我们先来讨论特殊情况(ET模式),再来讨论 ...

  3. Linux环境SOCKET编程1:套接字

    一.socket运行过程 服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接.在这时如果有个客户端初始化一个Socket,然 ...

  4. Linux下Socket编程

    Linux下Socket编程    网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符.Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的S ...

  5. Linux的SOCKET编程 简单演示

    转载:http://blog.csdn.net/hguisu/article/details/7445768/ Linux的SOCKET编程详解 1. 网络中进程之间如何通信 进 程通信的概念最初来源 ...

  6. asp.core api 通过socket和服务器通信发送udp_详解Linux的SOCKET编程

    文章来自于 https://www.zhangshengrong.com/p/9Oabd95XdK/ PHP进阶学习交流QQ群:983229225 本篇文章对Linux的SOCKET编程进行了详细解释 ...

  7. LINUX下Socket编程 函数格式详解

    你需要了解的一些系统调用: socket() bind() connect() listen() accept() send() recv() sendto() recvfrom() close() ...

  8. Linux的SOCKET编程详解

    Linux的SOCKET编程详解 一. 网络中进程之间如何通信 进程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系统 ...

  9. Linux的SOCKET编程详解——非常叼

    http://blog.csdn.net/hguisu/article/details/7445768/ 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] Linux的SOCKE ...

最新文章

  1. 【深度学习理论】(3) 激活函数
  2. js学习笔记——在html中嵌入脚本
  3. C语言递归实现深度优先搜索DFS算法(附完整源码)
  4. qt 操作html,如何在Webkit窗口中操作页面内容(使用QT和QTWebKit)?
  5. 汪子熙微信公众号的写作计划
  6. mybatis crud_MyBatis教程– CRUD操作和映射关系–第1部分
  7. Java转型(向上转型和向下转型)
  8. c语言encoder作业字符数组,C语言练习题库----数组
  9. 直接请求接口_【分享】接口是什么?实现原理的是什么?
  10. JAVA编程练习50题超详细
  11. php laravel 中文手册,Laravel 5.6 中文离线手册文档(兼容5.5)(PDF版)
  12. 软件工程第三章(第一部分)
  13. 「 Adams 」如何设置积分器与求解器类型
  14. 学习halcon之颜色识别
  15. js中的shift()函数
  16. 【项目实训】实验八 数据处理
  17. 苹果电脑安装计算机一级,偷天换日!让普通笔记本安装苹果系统
  18. 鸿蒙手机系统新桌面布局,鸿蒙系统是什么样的界面,详解华为鸿蒙系统
  19. Adding Animations之Zooming a View
  20. MegaCli的简易使用(命令总结)

热门文章

  1. 二维平面坐标系中,判断某点是否在正六边形内 | python 实现 + 数学推导(已知正六边形六个顶点坐标)
  2. 什么样的 python 可以可谓专业 PyPI 项目?刚刚学到三个概念:pep8、Sphinx、pytest与GitHub Action的集成
  3. iOS 开发笔记-加载/初始化
  4. 2021年上海高考小三门成绩查询,高考小三门怎么算分 上海2021高考小三门
  5. php dat文件,window_Win7系统怎么打开Dat文件 Win7系统打开Dat文件的方法,  在电脑中的Dat文件是很常 - phpStudy...
  6. mysql 存储过程 光标_mysql存储过程 光标
  7. qt调试失败问题跟踪
  8. Ubuntu OpenCV 自定义环境变量 pkg-config / PKGCONFIGPATH
  9. TYVJ1467 通往聚会的道路
  10. Oauth2与授权管理