#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. Atitit vue.js 把ajax数据 绑定到form表单

    Atitit vue.js 把ajax数据 绑定到form表单 1.1. 使用场景:主要应用在编辑与提交场合..1 1.2. 绑定数据到form控件,可以使用jquery,不过vue.js更加简单1 ...

  2. 文档 - STOMP Over WebSocket

    http://jmesnil.net/stomp-websocket/doc/ What is STOMP? STOMP is a simple text-orientated messaging p ...

  3. K8S 详细介绍

    k8s的中文文档,参考地址:http://docs.kubernetes.org.cn/227.html

  4. FLINK 案例分析

    基于Flink流处理的动态实时超大规模用户行为分析 https://zhuanlan.zhihu.com/p/31548501 基于Flink流处理的动态实时超大规模用户行为分析 https://zh ...

  5. PHP网站环境搭配: Apache Http+PHP+Mysql

    Apache Http+PHP+Mysql 环境搭配 1. 先下载上述三个软件 都要下载对应系统的软件,mysql还可以再下载navicat for mysql. 2.  安装Apache Http ...

  6. position: absolute;

    .recent-contac { position: absolute; overflow: auto; overflow-x: hidden; top: -2px; bottom: 0; -webk ...

  7. 在CentOS6.5上安装/启动PostgreSQL

    CentOS install PostgreSQL yum install postgresql-server Start PostgreSQL service postgresql initdb # ...

  8. 用nodejs的express框架在本机快速搭建一台服务器

    [本文出自天外归云的博客园] 简介 用express框架在本机搭建一个服务器,这样大家可以通过指定的url来在你的服务器上运行相应的功能. Express是一个基于nodejs的框架,我们可以用它来完 ...

  9. php类库安装xml

    问题 报错:Call to undefined function dom_import_simplexml() yum install php-dom service restart httpd 参考 ...

  10. JS实现多行文本最后是省略号紧随其后还有个超链接在同一行的需求

    1.布局及样式如下图: 2.js获得上图的div对象,然后判断div对象的高度,如果大于一行的高度了表示内容有两行了,再获得span标签里面的内容并用正则将后六个字符替换成“......”这里的实现代 ...