Linux epoll版定时器
#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 = # addFdToEpoll(epfd, pstParam); epollWait(epfd); //关闭定时器文件描述符
close(tfd); DE_FREE(pstParam); return ;
} int main()
{
test();
getchar();
return ;
}
Linux epoll版定时器的更多相关文章
- Java NIO系列教程(七) selector原理 Epoll版的Selector
目录: Reactor(反应堆)和Proactor(前摄器) <I/O模型之三:两种高性能 I/O 设计模式 Reactor 和 Proactor> <[转]第8章 前摄器(Proa ...
- 源码剖析Linux epoll实现机制及Linux上惊群
转载:https://blog.csdn.net/tgxallen/article/details/78086360 看源码是对一个技术认识最直接且最有效的方式了,之前用Linux Epoll做过一个 ...
- 如何在Python中使用Linux epoll
如何在Python中使用Linux epoll 内容 介绍 阻塞套接字编程示例 异步套接字和Linux epoll的好处 epoll的异步套接字编程示例 性能考量 源代码 介绍 从2.6版开始,Pyt ...
- 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验
在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...
- 2016 最佳 Linux 发行版排行榜
2015年,不管在企业市场还是个人消费市场都是 Linux非常重要的一年.作为一个自2005年起就开始使用 Linux的 Linuxer ,我门见证了 Linux在过去十年的成长.2016 Linux ...
- 构建自己的 Linux 发行版
如何用 SUSE Studio 构建 Linux 发行版? (1) 进入到 www.susestudio.com,设立一个帐户 (2) 为你的设备(发行版)选择一个基本模板 -软件和软件包选择 (1) ...
- linux发行版基础目录
linux发行版基础目录 linux 基础目录 linux基础目录 目录 作用 / 根目录,起源 /boot linux引导启动目录 /lib 库目录 /bin 常用内部命令 /sbin 常用内部管理 ...
- 2016年最佳Linux发行版排行榜
2015年,不管在企业市场还是个人消费市场都是 Linux 非常重要的一年. 最好的回归发行版:openSUSE openSUSE 背后的 SUSE 公司是最老的 Linux 企业,它成立于 Linu ...
- 最适合和最不适合新手使用的几款 Linux 发行版
大多数知名的Linux发行版都属于"比较容易使用"这一类.一些观察人士可能会驳斥这个观点,但事实上,说到Linux,大多数并非从事IT或软件开发工作的人会被最容易的使用体验所吸引. ...
随机推荐
- 绝对路径${pageContext.request.contextPath}用法及其与web.xml中Servlet的url-pattern匹配过程
以系统的一个“添加商品”的功能为例加以说明,系统页面为add.jsp,如图一所示: 图一 添加商品界面 系统的代码目录结构及add.jsp代码如图二所示: 图二 系统的代码目录结构及add.js ...
- Android 移动端数据结构
## SparseArray ## SparseBooleanArray ## SparseIntArray ## SparseLongArray * 位于android.util,Android 中 ...
- jQuery添加/改变/移除CSS类
转自:http://www.jbxue.com/article/24589.html 在jquery中用到removeClass移除CSS类.addClass添加CSS类.toggleClass添加或 ...
- 【Unity】6.2 在VS2015中调试 C# 脚本
分类:Unity.C#.VS2015 创建日期:2016-04-16 一.简介 这一节先利用GUI显示一个简单的界面(以后还会专门介绍GUI),并解释如何在VS2015中调试C#脚本. 本节例子的运行 ...
- javascript基础拾遗(九)
1.class关键字 ES6引入了新的class关键字编写对象 function Language(name){ this.name = name this.score = 8.0 } Languag ...
- 每日英语:The Most Destructive, Unpredictable Force in Tech
What's the most destructive force in the tech world, the thing that has nearly killed BlackBerry, pu ...
- 深度 | 机器学习敲门砖:任何人都能看懂的TensorFlow介绍【转】
转自:http://oicwx.com/detail/1161517 选自 kdnuggets 作者:Soon Hin Khor 机器之心编译 参与:Rick.吴攀.李亚洲 本文是日本东京 Tenso ...
- 三角形(css3)
.userCard .sanjiao {//三角形的制作: width: 0; height: 0; border-left: 10px solid transparent; border-right ...
- keepalived+nginx双机热备+负载均衡
Reference: http://blog.csdn.net/e421083458/article/details/30092795 keepalived+nginx双机热备+负载均衡 最近因业务扩 ...
- Ubuntu常用安装源
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak #备份 sudo vim /etc/apt/sources.list #修改 sudo ...