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或软件开发工作的人会被最容易的使用体验所吸引. ...
随机推荐
- UISwipeGestureRecognizer 左右事件捕捉
转自:http://blog.163.com/china_uv/blog/static/117137267201252102612185/ UISwipeGestureRecognizer 左右事件相 ...
- linux关闭selinux和firewall
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config setenforce 0
- 菜鸟学Java(十)——分页查询
今天继续跟大家说说一些非常基础的东西,这次我们说说分页查询.说到分页,可能很多人都听说过什么真分页.假分页的.简单解释一下,拿第二页,每页20条为例:真分:数据库里取 的就是21-40条:假分:数据库 ...
- ASP.NET Core2.0 环境下MVC模式的支付宝PC网站支付接口-沙箱环境开发测试
1.新建.NET Core web项目 2.Controllers-Models-Views 分三个大部分 3.下载安装最新sdk 官方的SDK以及Demo都还是.NET Framework的,根据官 ...
- Fabric V1 交易的生命周期
Fabric v1 Transaction Lifecycle1 Client application creates tran proposeal (chinacode function and a ...
- [Windows Azure] Virtual Machine and Cloud Service Sizes for Windows Azure
Virtual machine size CPU cores Memory OS disk space–cloud services OS disk space–virtual machines Ma ...
- lua面向对象编程之点号与冒号的差异详细比较
首先,先来一段在lua创建一个类与对象的代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Class = {} Class.__index = Cl ...
- 分布式系统唯一ID生成方案汇总【转】
转自:http://www.cnblogs.com/haoxinyue/p/5208136.html 系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结.生成ID的方法有很 ...
- tf.placeholder
tf.placeholder placeholder( dtype, shape=None, name=None ) 功能说明: 是一种占位符,在执行时候需要为其提供数据 参数列表: 参数名 必选 类 ...
- hdu3938(最小生成树,推荐)
题意描述:简单的讲就是,给你一张无向图,求有多少条路径使得路径上的花费小于L,这里路径上的花费是这样规定的,a.b两点之间的多条路径中的最长的边最小值! 思路:这题目有多个询问,肯定要用离线输出.思路 ...