网上关于timerfd的文章很多,在这儿归纳总结一下方便以后使用,顺便贴出一个timerfd配合epoll使用的简单例子

一、timerfd系列函数

  timerfd是Linux为用户程序提供的一个定时器接口。这个接口基于文件描述符,通过文件描述符的可读事件进行超时通知,因此可以配合select/poll/epoll等使用。
下面对timerfd系列函数先做一个简单的介绍:

(1)timerfd_create()函数

#include <sys/timerfd.h>

int timerfd_create(int clockid, int flags);
/*
timerfd_create()函数创建一个定时器对象,同时返回一个与之关联的文件描述符。
clockid:clockid标识指定的时钟计数器,可选值(CLOCK_REALTIME、CLOCK_MONOTONIC。。。)
CLOCK_REALTIME:系统实时时间,随系统实时时间改变而改变,即从UTC1970-1-1 0:0:0开始计时,中间时刻如果系统时间被用户改成其他,则对应的时间相应改变
CLOCK_MONOTONIC:从系统启动这一刻起开始计时,不受系统时间被用户改变的影响
flags:参数flags(TFD_NONBLOCK(非阻塞模式)/TFD_CLOEXEC(表示当程序执行exec函数时本fd将被系统自动关闭,表示不传递)
*/

(2)timerfd_settime()函数

 #include <sys/timerfd.h>

 struct timespec {
time_t tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds */
}; struct itimerspec {
struct timespec it_interval; /* Interval for periodic timer (定时间隔周期)*/
struct timespec it_value; /* Initial expiration (第一次超时时间)*/
};
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
/*
timerfd_settime()此函数用于设置新的超时时间,并开始计时,能够启动和停止定时器;
fd: 参数fd是timerfd_create函数返回的文件句柄
flags:参数flags为1代表设置的是绝对时间(TFD_TIMER_ABSTIME 表示绝对定时器);为0代表相对时间。
new_value: 参数new_value指定定时器的超时时间以及超时间隔时间
old_value: 如果old_value不为NULL, old_vlaue返回之前定时器设置的超时时间,具体参考timerfd_gettime()函数 ** it_interval不为0则表示是周期性定时器。
it_value和it_interval都为0表示停止定时器
*/

(3)timerfd_gettime()函数

 int timerfd_gettime(int fd, struct itimerspec *curr_value);
/*
timerfd_gettime()函数获取距离下次超时剩余的时间
curr_value.it_value 字段表示距离下次超时的时间,如果改值为0,表示计时器已经解除
改字段表示的值永远是一个相对值,无论TFD_TIMER_ABSTIME是否被设置
curr_value.it_interval 定时器间隔时间
*/
 uint64_t exp = ;
read(fd, &exp, sizeof(uint64_t));
//可以用read函数读取计时器的超时次数,改值是一个8字节无符号的长整型

(4)下面贴出一个timerfd配合epoll函数的简单例子

 /********************************************************
* Filename: timerfd.c
* Author: zhangwj
* Desprition: a sample program of timerfd
* Date: 2017-04-17
* Warnning:
********************************************************/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <sys/epoll.h>
#include <sys/timerfd.h> #if 0
struct timespec {
time_t tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds */
}; struct itimerspec {
struct timespec it_interval; /* Interval for periodic timer */
struct timespec it_value; /* Initial expiration */
};
#endif #define EPOLL_LISTEN_CNT 256
#define EPOLL_LISTEN_TIMEOUT 500 #define LOG_DEBUG_ON 1 #ifdef LOG_DEBUG_ON
#define LOG_DEBUG(fmt, args...) \
do { \
printf("[DEBUG]:");\
printf(fmt "\n", ##args); \
} while();
#define LOG_INFO(fmt, args...) \
do { \
printf("[INFO]:");\
printf(fmt "\n", ##args); \
} while();
#define LOG_WARNING(fmt, args...) \
do { \
printf("[WARNING]:");\
printf(fmt "\n", ##args); \
} while();
#else
#define LOG_DEBUG(fmt, args...)
#define LOG_INFO(fmt, args...)
#define LOG_WARNING(fmt, args...)
#endif
#define LOG_ERROR(fmt, args...) \
do{ \
printf("[ERROR]:");\
printf(fmt "\n", ##args);\
}while(); #define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while () static int g_epollfd = -;
static int g_timerfd = -;
uint64_t tot_exp = ; static void help(void)
{
exit();
} static void print_elapsed_time(void)
{
static struct timespec start;
struct timespec curr;
static int first_call = ;
int secs, nsecs; if (first_call) {
first_call = ;
if (clock_gettime(CLOCK_MONOTONIC, &start) == -)
handle_error("clock_gettime");
} if (clock_gettime(CLOCK_MONOTONIC, &curr) == -)
handle_error("clock_gettime"); secs = curr.tv_sec - start.tv_sec;
nsecs = curr.tv_nsec - start.tv_nsec;
if (nsecs < ) {
secs--;
nsecs += ;
}
printf("%d.%03d: ", secs, (nsecs + ) / );
} void timerfd_handler(int fd)
{
uint64_t exp = ; read(fd, &exp, sizeof(uint64_t));
tot_exp += exp;
print_elapsed_time();
printf("read: %llu, total: %llu\n", (unsigned long long)exp, (unsigned long long)tot_exp); return;
} void epoll_event_handle(void)
{
int i = ;
int fd_cnt = ;
int sfd;
struct epoll_event events[EPOLL_LISTEN_CNT]; memset(events, , sizeof(events));
while()
{
/* wait epoll event */
fd_cnt = epoll_wait(g_epollfd, events, EPOLL_LISTEN_CNT, EPOLL_LISTEN_TIMEOUT);
for(i = ; i < fd_cnt; i++)
{
sfd = events[i].data.fd;
if(events[i].events & EPOLLIN)
{
if (sfd == g_timerfd)
{
timerfd_handler(sfd);
}
}
}
}
} int epoll_add_fd(int fd)
{
int ret;
struct epoll_event event; memset(&event, , sizeof(event));
event.data.fd = fd;
event.events = EPOLLIN | EPOLLET; ret = epoll_ctl(g_epollfd, EPOLL_CTL_ADD, fd, &event);
if(ret < ) {
LOG_ERROR("epoll_ctl Add fd:%d error, Error:[%d:%s]", fd, errno, strerror(errno));
return -;
} LOG_DEBUG("epoll add fd:%d--->%d success", fd, g_epollfd);
return ;
} int epollfd_init()
{
int epfd; /* create epoll fd */
epfd = epoll_create(EPOLL_LISTEN_CNT);
if (epfd < ) {
LOG_ERROR("epoll_create error, Error:[%d:%s]", errno, strerror(errno));
return -;
}
g_epollfd = epfd;
LOG_DEBUG("epoll fd:%d create success", epfd); return epfd;
} int timerfd_init()
{
int tmfd;
int ret;
struct itimerspec new_value; new_value.it_value.tv_sec = ;
new_value.it_value.tv_nsec = ;
new_value.it_interval.tv_sec = ;
new_value.it_interval.tv_nsec = ; tmfd = timerfd_create(CLOCK_MONOTONIC, );
if (tmfd < ) {
LOG_ERROR("timerfd_create error, Error:[%d:%s]", errno, strerror(errno));
return -;
} ret = timerfd_settime(tmfd, , &new_value, NULL);
if (ret < ) {
LOG_ERROR("timerfd_settime error, Error:[%d:%s]", errno, strerror(errno));
close(tmfd);
return -;
} if (epoll_add_fd(tmfd)) {
close(tmfd);
return -;
}
g_timerfd = tmfd; return ;
} int main(int argc, char **argv)
{
if (epollfd_init() < ) {
return -;
} if (timerfd_init()) {
return -;
} /* event handle */
epoll_event_handle(); return ;
}

参考资料:

http://www.man7.org/linux/man-pages/man2/timerfd_create.2.html

http://blog.csdn.net/walkingman321/article/details/6162055

linux timerfd系列函数总结的更多相关文章

  1. Linux中exec()执行文件系列函数的使用说明

    函数原型: 描述:    exec()系列函数使用新的进程映像替换当前进程映像.    工作方式没有什么差别, 只是参数传递的方式不同罢了. 说明:    1. 这6个函数可分为两大类: execl( ...

  2. Linux Shell系列教程之(十五) Shell函数简介

    本文是Linux Shell系列教程的第(十五)篇,更多Linux Shell教程请看:Linux Shell系列教程 函数可以将一个复杂功能划分成若干模块,从而使程序结构更加清晰,代码重复利用率更高 ...

  3. linux tricks 之VA系列函数.

    VA函数(variable argument function),参数个数可变函数,又称可变参数函数.C/C++编程中,系统提供给编程人员的va函数很少.*printf()/*scanf()系列函数, ...

  4. linux系统编程之进程(五):exec系列函数(execl,execlp,execle,execv,execvp)使用

    本节目标: exec替换进程映像 exec关联函数组(execl.execlp.execle.execv.execvp) 一,exec替换进程映像 在进程的创建上Unix采用了一个独特的方法,它将进程 ...

  5. posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序

    posix 线程(一):线程模型.pthread 系列函数 和 简单多线程服务器端程序 一.线程有3种模型,分别是N:1用户线程模型,1:1核心线程模型和N:M混合线程模型,posix thread属 ...

  6. c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度

    linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1, ...

  7. c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信

    linux epoll系列2 利用epoll_wait查看是否可以送信 write函数本来是非阻塞函数,但是当缓存区被写满后,再往缓存区里写的时候,就必须等待缓存区再次变成可写,所以这是write就变 ...

  8. c/c++ linux epoll系列1 创建epoll

    linux epoll系列1 创建epoll 据说select和poll的弱点是,随着连接(socket)的增加,性能会直线下降. epoll不会随着连接(socket)的增加,性能直线下降. 知识点 ...

  9. c/c++ linux 进程间通信系列5,使用信号量

    linux 进程间通信系列5,使用信号量 信号量的工作原理: 由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的: P(sv):如果sv的值大于零,就给它减1:如果 ...

随机推荐

  1. CRM导入组织报实例名称必须与计算机名称相同的问题

    今天采用P2V拷贝了一台CRM数据库到虚机上,因为要加域必须得把计算机名改了,然后再重新导入组织的时候报错了:"实例名称必须与计算机名称相同",google了下没有匹配的问题答案, ...

  2. 【LaTeX排版】LaTeX论文模版

    本文是对前面LaTeX论文排版文章的总结.前面的几篇文章是分别从论文的几个方面来讲述LaTeX的排版问题,这里综合了前面的内容,给出了论文排版的模版. 模版的使用: 1.首先建立一个main.tex文 ...

  3. 销售行业ERP数据统计分析都有哪些维度?

    场景描述 当前的企业信息化建设主要包括ERP系统.OA系统等.企业希望实现信息系统数据的整合,对企业资源进行分析汇总,方便对企业相关数据的掌控从而便于对业务流程进行及时调整监控. 但是由于系统间数据的 ...

  4. OpenCV——PS 滤镜, 浮雕效果

    具体的算法原理可以参考: PS 滤镜, 浮雕效果 // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITH ...

  5. 【Android 应用开发】BluetoothClass详解

    一. BluetoothClass简介 1. 继承关系 public final class BluetoothClass extends Object implements Parcelable 该 ...

  6. 《万能数据库查询分析器》实现使用SQL语句直接高效地访问文本文件

    <万能数据库查询分析器>实现使用SQL语句直接高效地访问文本文件 马根峰 (广东联合电子服务股份有限公司, 广州 510300) 摘要    用SQL语句来直接访问文本文件?是在做梦吗? ...

  7. LeetCode(40)-Merge Sorted Array

    听到初爱有感 开头啰嗦两句,刚在做算法题目的时候,听到了杨宗纬的<初爱>,突然有了一种本科时候的感觉,想想自己现在研二了,青春喂了狗,我果断喝了一罐啤酒,循环这首歌到吐-.. 题目: Gi ...

  8. .haccess 配置生效

    前言:网上看到有写用.haccess会影响到网站速率之类的,这里只是讲解自己的一点配置.haccess的心得,其它的之后再讨论哈~ 1.普通配置: 网上都有的那种配置   apache/conf/ht ...

  9. SQL Server 表的管理_关于完整性约束的详解(案例代码)

    SQL Server 表的管理之_关于完整性约束的详解 一.概述: ●约束是SQL Server提供的自动保持数据库完整性的一种方法, 它通过限制字段中数据.记录中数据和表之间的数据来保证数据的完整性 ...

  10. mac port 清理

    http://popozhu.github.io/2014/10/27/mac-port-%E6%B8%85%E7%90%86/ 使用 mac port 来安装一些软件,时间久了后(也有两年多),更新 ...