转自:https://www.jianshu.com/p/66b3c75cae81

timerfd为Linux为用户程序提供的定时器接口,该接口基于文件描述符,通过文件描述符的可读事件进行超时通知,且能够被用于epoll/select。主要有三个函数。

头文件: include <sys/timerfd.h>

int timerfd_create(int clockid, int flags)

功能: 生成定时器,返回文件描述符。
clockid: CLOCK_MONOTONIC或CLOCK_REALTIME,其中CLOCK_MONOTONIC表示获取的时间为系统重启到现在的时间,更改系统时间对其没有影响。CLOCK_REALTIME表示从1970.1.1到目前的时间,更改系统时间会更改获取的值。
flags: TFD_NONBLOCK(非阻塞), TFD_CLOEXEC(同O_CLOEXEC)。
return: timer的文件描述符。

int timerfd_settime(int tfd, int flags, const struct itimerspec *newValue, struct itimerspec *oldValue)

功能: 用于启动或关闭指定fd的定时器。
tfd: timerfd,由timerfd_create函数返回。
flags: 1表示设置的是绝对时间;0表示相对时间。
newValue: 指定新的超时时间,若newValue.it_value非0则启动定时器,否则关闭定时器。若newValue.it_interval为0则定时器只定时一次,否则之后每隔设定时间超时一次。
oldValue:不为NULL时则返回定时器这次设置之前的超时时间。
return:失败则返回-1。

struct timespec
{
time_t tv_sec; //秒
long tv_nsec; //纳秒
}
struct itimerspec
{
struct timespec it_interval; //首次超时后,每隔it_interval超时一次
struct timespec it_value; //首次超时时间
}

int timerfd_gettime(int fd, struct itimerspec *curValue)

功能: 用于获取距离下次超时还剩下的时间。如果调用时定时器已经到期(即超过it_value时间),并且定时器处于循环模式(即it_interval不为0), 那么调用该函数后定时器重新开始计时。
fd: timerfd,由timerfd_create函数返回。
curValue: 返回距离下次超时剩下的时间。
return:失败返回-1

读取timerfd

当定时器超时,timerfd可读,返回uint64_t类型的整数,为超时的数目(指有多少个超时未读),如果定时器没有发生超时事件,若timerfd为阻塞时,read将阻塞,若timerfd为非阻塞时,返回EAGAIN错误。如果read是的数据小于8字节以EINVAL错误返回。

样例代码

#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;
}

小礼物走一走,来简书关注我

作者:agin719
链接:https://www.jianshu.com/p/66b3c75cae81
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

Linux Timer定时器【转】的更多相关文章

  1. 浅析linux内核中timer定时器的生成和sofirq软中断调用流程(转自http://blog.chinaunix.net/uid-20564848-id-73480.html)

    浅析linux内核中timer定时器的生成和sofirq软中断调用流程 mod_timer添加的定时器timer在内核的软中断中发生调用,__run_timers会spin_lock_irq(& ...

  2. 浅析linux内核中timer定时器的生成和sofirq软中断调用流程【转】

    转自:http://blog.chinaunix.net/uid-20564848-id-73480.html 浅析linux内核中timer定时器的生成和sofirq软中断调用流程 mod_time ...

  3. 芯灵思Sinlinx A64开发板Linux内核定时器编程

    开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板详细参数 https://m.tb.cn/h.3wMaSKm 开发板交流群 641395230 Linux 内核定时器是内 ...

  4. 全志A33开发板Linux内核定时器编程

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 Linux 内核定时器是内核 ...

  5. 芯灵思SinlinxA33开发板Linux内核定时器编程

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 Linux 内核定时器是内核 ...

  6. Linux内核 - 定时器

    #include <linux/timer.h> //头文件 struct timer_list mytimer; //定义变量 static void my_timer(unsigned ...

  7. linux内核--定时器API

    /**<linux/timer.h> 定时器结构体 struct timer_list { ........ unsigned long expires; --内核希望定时器执行的jiff ...

  8. Linux内核定时器struct timer_list

    1.前言 Linux内核中的定时器是一个很常用的功能,某些需要周期性处理的工作都需要用到定时器.在Linux内核中,使用定时器功能比较简单,需要提供定时器的超时时间和超时后需要执行的处理函数. 2.常 ...

  9. linux 内核定时器

    无论何时你需要调度一个动作以后发生, 而不阻塞当前进程直到到时, 内核定时器是给你 的工具. 这些定时器用来调度一个函数在将来一个特定的时间执行, 基于时钟嘀哒, 并且 可用作各类任务; 例如, 当硬 ...

随机推荐

  1. (转)广度优先搜索BFS和深度优先搜索DFS

    1. 广度优先搜索介绍 广度优先搜索算法(Breadth First Search),又称为"宽度优先搜索"或"横向优先搜索",简称BFS. 它的思想是:从图中 ...

  2. Ubuntu 14.04 installation & bugs on Alienware-13

    列一下Alienware 13笔记本配置: Processor: Intel Core 5th Generation i5-5200U Processor (3M Cache, up to 2.70 ...

  3. wifi 标准

    简介 https://smb.pconline.com.cn/1149/11491365.html

  4. sql 索引 sql_safe_updates

    为了数据的安全性,mysql有一个安全性设置,sql_safe_updates ,当把这个值设置成1的时候,当程序要对数据进行修改删除操作的时候条件必须要走索引. 刚好现在也碰到了此类问题:网上找了相 ...

  5. html5 & input & accept attribute

    html5 & input & accept attribute html input accept attribute https://www.w3schools.com/TAGS/ ...

  6. canvas技术整理

    canvas技术整理 html <canvas id= "canvas"></canvas> javascript var canvas = documen ...

  7. TCP 协议连接与关闭的握手

     原文链接 http://blog.csdn.net/oney139/article/details/8103223   TCP头部: 其中 ACK   SYN  序号  这三个部分在以下会用到,它们 ...

  8. 【刷题】BZOJ 2935 [Poi1999]原始生物

    Description 原始生物的遗传密码是一个自然数的序列K=(a1,...,an).原始生物的特征是指在遗传密码中连续出现的数对(l,r),即存在自然数i使得l=ai且r=ai+1.在原始生物的遗 ...

  9. 基于Spark Mllib的文本分类

    基于Spark Mllib的文本分类 文本分类是一个典型的机器学习问题,其主要目标是通过对已有语料库文本数据训练得到分类模型,进而对新文本进行类别标签的预测.这在很多领域都有现实的应用场景,如新闻网站 ...

  10. bzoj1052

    Description 某人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄 膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将 ...