#ifndef __MYTIMER_H_
#define __MYTIMER_H_ /***************
高并发场景下的定时器
*****************/ //定时器回调函数
typedef void *(*TimerCallback)(int fd, void *); typedef enum enFD_TYPE
{
FD_TIMER,
FD_SOCKET,
FD_FILE,
}ENFD_TYPE; struct STEpollParam
{
int fd; //文件描述符
ENFD_TYPE enType; //文件描述符类型
TimerCallback cb; //定时器回调函数
void * pvParam; //回调函数参数
}; //创建定时器对象
int createTimer(unsigned int uiSec, unsigned int uiNsec); //设置文件描述符非阻塞
int setNoBlock(int fd); //创建epoll
int createEpoll(); //添加文件描述符到epoll
int addFdToEpoll(int epfd, STEpollParam *pstParam); //消息处理
int recvMsg(void *pvParam); //等待消息
void epollWait(int epfd); #endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <string.h> #include "comontype.h"
#include "mytimer.h" #define EPOOL_SIZE 32000
#define EPOOL_EVENT 32 /********************************************************
Func Name: createTimer
Date Created: 2018-7-30
Description: 创建定时器对象
Input: uiTvSec:设置间隔多少秒
uiTvUsec:设置间隔多少微秒
Output:
Return: 文件句柄
Caution:
*********************************************************/
int createTimer(unsigned int uiSec, unsigned int uiNsec)
{
int iRet = ;
int tfd = ;
struct itimerspec timeValue; //初始化定时器
/*
When the file descriptor is no longer required it should be closed.
When all file descriptors associated with the same timer object have been closed,
the timer is disarmed and its resources are freed by the kernel. 意思是该文件句柄还是需要调用close函数关闭的
*/
tfd = timerfd_create(CLOCK_REALTIME,);
if (tfd < )
{
return -;
} //设置开启定时器
/*
Setting either field of new_value.it_value to a nonzero value arms the timer.
Setting both fields of new_value.it_value to zero disarms the timer.
意思是如果不设置it_interval的值非零,那么即关闭定时器
*/
timeValue.it_value.tv_sec = ;
timeValue.it_value.tv_nsec = ; //设置定时器周期
timeValue.it_interval.tv_sec = (time_t)uiSec;
timeValue.it_interval.tv_nsec = (long)uiNsec; iRet = timerfd_settime(tfd, , &timeValue, NULL);
if (iRet < )
{
return -;
} return tfd;
} /********************************************************
Func Name: setNoBlock
Date Created: 2018-7-27
Description: 设置文件描述符非阻塞
Input: fd:文件描述符
Output:
Return: error code
Caution:
*********************************************************/
int setNoBlock(IN int fd)
{
int iRet = DEFAULT_ERROR; int iOption = -; iOption = fcntl(fd, F_GETFD);
if(iOption < )
{
iRet = DEFAULT_ERROR;
return iRet;
} iOption = iOption | O_NONBLOCK; iOption = fcntl(fd,F_SETFD,iOption);
if(iOption < )
{
iRet = DEFAULT_ERROR;
return iRet;
} return RESULT_OK;
} /********************************************************
Func Name: createEpoll
Date Created: 2018-7-30
Description: 创建epoll
Input:
Output:
Return: epoll句柄
Caution:
*********************************************************/
int createEpoll()
{
int epfd = ; /*
When no longer required,
the file descriptor returned by epoll_create() should be closed byusing close(2).
When all file descriptors referring to an epoll instance have been closed,
the kernel destroys the instance and releases the associated resources for reuse. 意思是用完需要调用close函数关闭epoll句柄
*/
epfd = epoll_create(EPOOL_SIZE);
if (epfd < )
{
return -;
} return epfd;
} /********************************************************
Func Name: addFdToEpoll
Date Created: 2018-7-30
Description: 添加文件描述符到epoll
Input:
Output:
Return: error code
Caution:
*********************************************************/
int addFdToEpoll(int epfd, STEpollParam *pstParam)
{
int iRet = DEFAULT_ERROR;
struct epoll_event ev;
ev.data.ptr = pstParam;
ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
iRet = epoll_ctl(epfd, EPOLL_CTL_ADD, pstParam->fd, &ev);
if (iRet < )
{
return DEFAULT_ERROR;
}
return RESULT_OK;
} /********************************************************
Func Name: recvMsg
Date Created: 2018-7-30
Description: 消息处理
Input: pvParam:参数指针
Output:
Return:
Caution:
*********************************************************/
int recvMsg(void *pvParam)
{
int iRet = DEFAULT_ERROR;
STEpollParam * pstParam = NULL; if (NULL == pvParam)
{
iRet = PARAM_ERROR;
return iRet;
}
pstParam = (STEpollParam *)pvParam;
switch(pstParam->enType)
{
case FD_TIMER:
pstParam->cb(pstParam->fd, pstParam->pvParam);
break;
default:
break;
}
return RESULT_OK;
} /********************************************************
Func Name: epollWait
Date Created: 2018-7-30
Description: 等待消息
Input: epfd:epoll句柄
Output:
Return:
Caution:
*********************************************************/
void epollWait(int epfd)
{
int i = ;
int nfds = ;
struct epoll_event *events = NULL; //分配epoll事件内存
events = (struct epoll_event *)malloc(sizeof(struct epoll_event)*EPOOL_EVENT);
if (NULL == events)
{
return ;
}
memset(events, , sizeof(struct epoll_event)*EPOOL_EVENT); for (;;)
{
nfds = epoll_wait(epfd, events, EPOOL_EVENT, -);
if (nfds < )
{
break;
}
for (i = ; i < nfds; i++ )
{
//监听读事件
if (events[i].events & EPOLLIN)
{
recvMsg(events[i].data.ptr);
}
}
} //关闭epoll
close(epfd); return ;
}
#include <iostream>

using namespace std;

#include "mytimer.h"

//#include <sys/timerfd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "comontype.h" #define INTERVAL 3 void * timerFunc(int fd, void *pvParam)
{
long data = ;
int *p = NULL; p = (int *)pvParam;
read(fd, &data, sizeof(long));
printf("data = %lu and p = %d \n", data, *p); return NULL;
} int test()
{
STEpollParam *pstParam =new STEpollParam;
int tfd = ;
int num = ; //初始化epoll
int epfd = createEpoll();
if (epfd < )
{
cout << "createEpoll() failed ." << endl;
return -;
}
//初始化定时器
tfd = createTimer(INTERVAL,);
if (tfd < )
{
cout << "createTimer() failed ." << endl;
return -;
} pstParam->fd = tfd;
pstParam->enType = FD_TIMER;
pstParam->cb = timerFunc;
pstParam->pvParam = &num; addFdToEpoll(epfd, pstParam); epollWait(epfd); //关闭定时器文件描述符
close(tfd); DE_FREE(pstParam); return ;
} int main()
{
test();
getchar();
return ;
}

Linux epoll版定时器的更多相关文章

  1. Java NIO系列教程(七) selector原理 Epoll版的Selector

    目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...

  2. 源码剖析Linux epoll实现机制及Linux上惊群

    转载:https://blog.csdn.net/tgxallen/article/details/78086360 看源码是对一个技术认识最直接且最有效的方式了,之前用Linux Epoll做过一个 ...

  3. 如何在Python中使用Linux epoll

    如何在Python中使用Linux epoll 内容 介绍 阻塞套接字编程示例 异步套接字和Linux epoll的好处 epoll的异步套接字编程示例 性能考量 源代码 介绍 从2.6版开始,Pyt ...

  4. 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验

    在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...

  5. 2016 最佳 Linux 发行版排行榜

    2015年,不管在企业市场还是个人消费市场都是 Linux非常重要的一年.作为一个自2005年起就开始使用 Linux的 Linuxer ,我门见证了 Linux在过去十年的成长.2016 Linux ...

  6. 构建自己的 Linux 发行版

    如何用 SUSE Studio 构建 Linux 发行版? (1) 进入到 www.susestudio.com,设立一个帐户 (2) 为你的设备(发行版)选择一个基本模板 -软件和软件包选择 (1) ...

  7. linux发行版基础目录

    linux发行版基础目录 linux 基础目录 linux基础目录 目录 作用 / 根目录,起源 /boot linux引导启动目录 /lib 库目录 /bin 常用内部命令 /sbin 常用内部管理 ...

  8. 2016年最佳Linux发行版排行榜

    2015年,不管在企业市场还是个人消费市场都是 Linux 非常重要的一年. 最好的回归发行版:openSUSE openSUSE 背后的 SUSE 公司是最老的 Linux 企业,它成立于 Linu ...

  9. 最适合和最不适合新手使用的几款 Linux 发行版

    大多数知名的Linux发行版都属于"比较容易使用"这一类.一些观察人士可能会驳斥这个观点,但事实上,说到Linux,大多数并非从事IT或软件开发工作的人会被最容易的使用体验所吸引. ...

随机推荐

  1. Linux学习笔记--SSH免password登录

    须要实现的效果: 有两台server:"192.168.201.236" 和 "192.168.201.237" 须要实现:在server"192.1 ...

  2. [hihoCoder] 第四十八周: 拓扑排序·二

    题目1 : 拓扑排序·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho所在学校的校园网被黑客入侵并投放了病毒.这事在校内BBS上立刻引起了大家的讨论,当 ...

  3. jsp页面中的EL表达式不被解析的问题

    原因:问题在web.xml配置文件上,web.xml声明部分一般分为如下版本的xsd, web-app_2_2.xsd web-app_2_3.xsd web-app_2_4.xsd web-app_ ...

  4. 用bundler安装jeklly

    为什么要写这篇文章呢?因为官方的安装文档里,ruby的很多库没有说明怎么安装.所以需要重点说明一下.1.我的安装环境是vultr的16.04版的ubuntu.2.因为ruby的扩展库好多都是Gcc编译 ...

  5. DevExpress GridControl List绑定方式下新增行的方法

    List<Person> gridDataList = new List<Person>(); //此处是数据源 List集合 BindingList<Person> ...

  6. 每日英语:The Power of Parents Who Say 'No'

    I grew up in an affluent area. Most kids owned multiple Cabbage Patch dolls and Gear bags and pairs ...

  7. 每日英语:How Often Do Gamblers Really Win?

    The casino billboards lining America's roadways tantalize with the lure of riches. 'Easy Street. It' ...

  8. 使用JPush(极光推送)实现远程通知

    使用JPush(极光推送)实现远程通知 远程推送是APP 必备的功能, 现在第三方的 SDK 已经做的非常完备了, 在 iOS10.0出来之后, 极光推送也及时更新了他的 SDK, 今天小试了一下效果 ...

  9. 安装Python2.7出现configure: error: no acceptable C compiler found in $PATH错误

    安装Python2.7出现configure: error: no acceptable C compiler found in $PATH错误 安装步骤: 安装依赖 yum groupinstall ...

  10. django HttpRequest对象

    概述: 服务器接收http请求后,会根据报文创建HttpRequest对象 视图的第一个参数就是HttpRequest对象 django创建的,之后调用视图时传递给视图 属性 path:请求的完整路径 ...