- ailx10:这里我想让程序定时2秒,打印一个tick,我要怎么做?
- 大黑客:这不很简单吗?
- ailx10:sleep就是个弟弟,能不能不用sleep做定时器?
- 大黑客:不用sleep怎么定时啊?
- ailx10:
Epoll + timerfd
- 大黑客:要不要这么专业啊?
- ailx10: 嘿嘿,我可是做hacker的男人,能不专业吗?
- 大黑客:那就开始你的表演吧 ...
这里有一个坑,我在写timer定时器的时候,发现read函数返回-1,错误码errno=22,说是参数错误,你绝对想不到第2个参数必须是uint64_t
类型。
read的函数原型:(大雾!定时器这里需要小心)
#include <unistd.h>
ssize_t read(int filedes, void *buf, size_t nbyetes);
主函数:
// main.c by ailx10
#include <stdio.h>
#include "epoll.h"
#include "timer.h"
int main()
{
ep_init();
timer_cre();
ep_wait();
return 0;
}
Epoll事件驱动函数:
// epoll.c by ailx10
#include <stdio.h>
#include <sys/epoll.h>
#include "epoll.h"
static int g_epfd = 0;
void ep_init()
{
int epfd = epoll_create(1);
g_epfd = epfd;
return ;
}
void ep_add(ep_entry_s* p)
{
struct epoll_event stEpEvent;
stEpEvent.events = EPOLLIN | EPOLLHUP | EPOLLERR;
stEpEvent.data.ptr = (void*)p;
epoll_ctl(g_epfd,EPOLL_CTL_ADD,p->fd,&stEpEvent);
return;
}
void ep_del(ep_entry_s* p)
{
struct epoll_event stEpEvent;
stEpEvent.events = EPOLLIN | EPOLLHUP | EPOLLERR;
stEpEvent.data.ptr = (void*)p;
epoll_ctl(g_epfd,EPOLL_CTL_DEL,p->fd,&stEpEvent);
return;
}
void ep_exit()
{
g_epfd = -1;
return;
}
void ep_wait()
{
int fd;
int num;
ep_entry_s* pstp;
ep_callback_func fcallback;
struct epoll_event astEvent[1];
while(1)
{
fd = epoll_wait(g_epfd,astEvent,1,-1);
for(num = 0; num < fd;++num)
{
pstp = (ep_entry_s*)astEvent[num].data.ptr;
fcallback = pstp->fCallback;
fcallback(astEvent[num].events,pstp->fd);
}
}
}
对应的头文件:
// epoll.h by ailx10
#include <stdio.h>
typedef int (*ep_callback_func)(int event,int fd);
typedef struct tagEpEntry
{
int fd;
ep_callback_func fCallback;
}ep_entry_s;
void ep_init();
void ep_add(ep_entry_s* p);
void ep_del(ep_entry_s* p);
void ep_exit();
void ep_wait();
定时器函数:
// timer.c by ailx10
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include "epoll.h"
#include "timer.h"
static ep_entry_s g_ep_entry = {-1,NULL};
static int _callback(int event,int fd)
{
uint64_t count = 0;
if(0 != (EPOLLIN & event))
{
int n =read(fd,(void*)&count,sizeof(count));
//printf("%d\n",n);
if (n > 0)
{
printf("tick.\n");
}
}
return 0;
}
void timer_cre()
{
struct itimerspec timer;
int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
printf("timefd=%d\n",timerfd);
memset(&timer,0,sizeof(timer));
timer.it_interval.tv_sec = 2;
timer.it_value.tv_sec = 2;
timerfd_settime(timerfd,0,&timer,NULL);
g_ep_entry.fd = timerfd;
g_ep_entry.fCallback = (ep_callback_func)_callback;
ep_add(&g_ep_entry);
return;
}
void _timer_del()
{
ep_del(&g_ep_entry);
close(g_ep_entry.fd);
g_ep_entry.fCallback = NULL;
return;
}
对应的头文件:
// timer.h by ailx10
#include <stdio.h>
void timer_cre();
谢谢阅读 ~