redis的定时任务是死循环+epoll_wait延时来实现的。其函数调用顺序是:
redis.c main 调用ae.c aeMain (死循环)
ae.c aeMain 调用 ae.c aeProcessEvents:
ae.c aeProcessEvents 调用 ae.c aeSearchNearestTimer(获取定时任务里下一个需要执行的任务)
ae.c aeProcessEvents 调用 ae_poll.c aeApiPoll(设置epoll_wait)
epoll_wait超时触发后,执行redis.c serverCron (由serverCron来调用各种具体的定时任务)
用epoll_wait实现定时器的示例:
#define MAX_EVENTS 1
#include <stdio.h> // for fprintf()
#include <unistd.h> // for close(), read()
#include <sys/epoll.h> // for epoll_create1(), epoll_ctl(), struct epoll_event
#include <string.h> // for strncmp
void serverCron(){
printf("serverCron is called\n");
}
int main()
{
int running = 1, event_count;
struct epoll_event event, events[1];
int epoll_fd = epoll_create(1024);
if(epoll_fd == -1)
{
fprintf(stderr, "Failed to create epoll file descriptor\n");
return 1;
}
if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, &event))
{
fprintf(stderr, "Failed to add file descriptor to epoll\n");
close(epoll_fd);
return 1;
}
while(running)
{
event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, 1000);
serverCron();
}
if(close(epoll_fd))
{
fprintf(stderr, "Failed to close epoll file descriptor\n");
return 1;
}
return 0;
}