Linux epoll版定时器

1#ifndef __MYTIMER_H_ 2#define __MYTIMER_H_ 3 4/*************** 5高并发场景下的定时器 6*****************/ 7 8//定时器回调函数 9typedef void *(*TimerCallback)(int fd, void *); 10 11typedef enum enFD_TYPE 12{ 13 FD_TIMER, 14 FD_SOCKET, 15 FD_FILE, 16}ENFD_TYPE; 17 18struct STEpollParam 19{ 20 int fd; //文件描述符 21 ENFD_TYPE enType; //文件描述符类型 22 TimerCallback cb; //定时器回调函数 23 void * pvParam; //回调函数参数 24}; 25 26//创建定时器对象 27int createTimer(unsigned int uiSec, unsigned int uiNsec); 28 29//设置文件描述符非阻塞 30int setNoBlock(int fd); 31 32//创建epoll 33int createEpoll(); 34 35//添加文件描述符到epoll 36int addFdToEpoll(int epfd, STEpollParam *pstParam); 37 38//消息处理 39int recvMsg(void *pvParam); 40 41//等待消息 42void epollWait(int epfd); 43 44#endif 45 46#include <stdio.h> 47#include <stdlib.h> 48#include <unistd.h> 49#include <fcntl.h> 50#include <sys/epoll.h> 51#include <sys/timerfd.h> 52#include <string.h> 53 54#include "comontype.h" 55#include "mytimer.h" 56 57#define EPOOL_SIZE 32000 58#define EPOOL_EVENT 32 59 60 61/******************************************************** 62 Func Name: createTimer 63Date Created: 2018-7-30 64 Description: 创建定时器对象 65 Input: uiTvSec:设置间隔多少秒 66 uiTvUsec:设置间隔多少微秒 67 Output: 68 Return: 文件句柄 69 Caution: 70*********************************************************/ 71int createTimer(unsigned int uiSec, unsigned int uiNsec) 72{ 73 int iRet = 0; 74 int tfd = 0; 75 struct itimerspec timeValue; 76 77 //初始化定时器 78 /* 79 When the file descriptor is no longer required it should be closed. 80 When all file descriptors associated with the same timer object have been closed, 81 the timer is disarmed and its resources are freed by the kernel. 82 83 意思是该文件句柄还是需要调用close函数关闭的 84 */ 85 tfd = timerfd_create(CLOCK_REALTIME,0); 86 if (tfd < 0) 87 { 88 return -1; 89 } 90 91 //设置开启定时器 92 /* 93 Setting either field of new_value.it_value to a nonzero value arms the timer. 94 Setting both fields of new_value.it_value to zero disarms the timer. 95 意思是如果不设置it_interval的值非零,那么即关闭定时器 96 */ 97 timeValue.it_value.tv_sec = 1; 98 timeValue.it_value.tv_nsec = 0; 99 100 //设置定时器周期 101 timeValue.it_interval.tv_sec = (time_t)uiSec; 102 timeValue.it_interval.tv_nsec = (long)uiNsec; 103 104 iRet = timerfd_settime(tfd, 0, &timeValue, NULL); 105 if (iRet < 0) 106 { 107 return -1; 108 } 109 110 return tfd; 111} 112 113/******************************************************** 114 Func Name: setNoBlock 115Date Created: 2018-7-27 116 Description: 设置文件描述符非阻塞 117 Input: fd:文件描述符 118 Output: 119 Return: error code 120 Caution: 121*********************************************************/ 122int setNoBlock(IN int fd) 123{ 124 int iRet = DEFAULT_ERROR; 125 126 int iOption = -1; 127 128 iOption = fcntl(fd, F_GETFD); 129 if(iOption < 0) 130 { 131 iRet = DEFAULT_ERROR; 132 return iRet; 133 } 134 135 iOption = iOption | O_NONBLOCK; 136 137 iOption = fcntl(fd,F_SETFD,iOption); 138 if(iOption < 0) 139 { 140 iRet = DEFAULT_ERROR; 141 return iRet; 142 } 143 144 return RESULT_OK; 145} 146 147/******************************************************** 148 Func Name: createEpoll 149Date Created: 2018-7-30 150 Description: 创建epoll 151 Input: 152 Output: 153 Return: epoll句柄 154 Caution: 155*********************************************************/ 156int createEpoll() 157{ 158 int epfd = 0; 159 160 /* 161 When no longer required, 162 the file descriptor returned by epoll_create() should be closed byusing close(2). 163 When all file descriptors referring to an epoll instance have been closed, 164 the kernel destroys the instance and releases the associated resources for reuse. 165 166 意思是用完需要调用close函数关闭epoll句柄 167 */ 168 epfd = epoll_create(EPOOL_SIZE); 169 if (epfd < 0) 170 { 171 return -1; 172 } 173 174 return epfd; 175} 176 177/******************************************************** 178 Func Name: addFdToEpoll 179Date Created: 2018-7-30 180 Description: 添加文件描述符到epoll 181 Input: 182 Output: 183 Return: error code 184 Caution: 185*********************************************************/ 186int addFdToEpoll(int epfd, STEpollParam *pstParam) 187{ 188 int iRet = DEFAULT_ERROR; 189 struct epoll_event ev; 190 ev.data.ptr = pstParam; 191 ev.events = EPOLLIN | EPOLLERR | EPOLLHUP; 192 iRet = epoll_ctl(epfd, EPOLL_CTL_ADD, pstParam->fd, &ev); 193 if (iRet < 0) 194 { 195 return DEFAULT_ERROR; 196 } 197 return RESULT_OK; 198} 199 200/******************************************************** 201 Func Name: recvMsg 202Date Created: 2018-7-30 203 Description: 消息处理 204 Input: pvParam:参数指针 205 Output: 206 Return: 207 Caution: 208*********************************************************/ 209int recvMsg(void *pvParam) 210{ 211 int iRet = DEFAULT_ERROR; 212 STEpollParam * pstParam = NULL; 213 214 if (NULL == pvParam) 215 { 216 iRet = PARAM_ERROR; 217 return iRet; 218 } 219 pstParam = (STEpollParam *)pvParam; 220 switch(pstParam->enType) 221 { 222 case FD_TIMER: 223 pstParam->cb(pstParam->fd, pstParam->pvParam); 224 break; 225 default: 226 break; 227 } 228 return RESULT_OK; 229} 230 231/******************************************************** 232 Func Name: epollWait 233Date Created: 2018-7-30 234 Description: 等待消息 235 Input: epfd:epoll句柄 236 Output: 237 Return: 238 Caution: 239*********************************************************/ 240void epollWait(int epfd) 241{ 242 int i = 0; 243 int nfds = 0; 244 struct epoll_event *events = NULL; 245 246 //分配epoll事件内存 247 events = (struct epoll_event *)malloc(sizeof(struct epoll_event)*EPOOL_EVENT); 248 if (NULL == events) 249 { 250 return ; 251 } 252 memset(events, 0, sizeof(struct epoll_event)*EPOOL_EVENT); 253 254 for (;;) 255 { 256 nfds = epoll_wait(epfd, events, EPOOL_EVENT, -1); 257 if (nfds < 0) 258 { 259 break; 260 } 261 for (i = 0; i < nfds; i++ ) 262 { 263 //监听读事件 264 if (events[i].events & EPOLLIN) 265 { 266 recvMsg(events[i].data.ptr); 267 } 268 } 269 } 270 271 //关闭epoll 272 close(epfd); 273 274 return ; 275} 276 277#include <iostream> 278 279using namespace std; 280 281#include "mytimer.h" 282 283//#include <sys/timerfd.h> 284#include <string.h> 285#include <stdlib.h> 286#include <stdio.h> 287#include <unistd.h> 288#include "comontype.h" 289 290#define INTERVAL 3 291 292void * timerFunc(int fd, void *pvParam) 293{ 294 long data = 0; 295 int *p = NULL; 296 297 p = (int *)pvParam; 298 read(fd, &data, sizeof(long)); 299 printf("data = %lu and p = %d \n", data, *p); 300 301 return NULL; 302} 303 304int test() 305{ 306 STEpollParam *pstParam =new STEpollParam; 307 int tfd = 0; 308 int num = 10; 309 310 //初始化epoll 311 int epfd = createEpoll(); 312 if (epfd < 0) 313 { 314 cout << "createEpoll() failed ." << endl; 315 return -1; 316 } 317 //初始化定时器 318 tfd = createTimer(INTERVAL,0); 319 if (tfd < 0) 320 { 321 cout << "createTimer() failed ." << endl; 322 return -1; 323 } 324 325 pstParam->fd = tfd; 326 pstParam->enType = FD_TIMER; 327 pstParam->cb = timerFunc; 328 pstParam->pvParam = &num; 329 330 addFdToEpoll(epfd, pstParam); 331 332 epollWait(epfd); 333 334 //关闭定时器文件描述符 335 close(tfd); 336 337 DE_FREE(pstParam); 338 339 return 0; 340} 341 342int main() 343{ 344 test(); 345 getchar(); 346 return 0; 347}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )