Chinaunix首页 | 黑桃棋牌官方网下载 | 博客
  • 博客访问: 535491
  • 博文数量: 78
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 973
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-21 22:26
  • 认证徽章:
  • 个人简介

    90后空巢老码农

    文章分类

    全部博文(78)

  • redis(33)
  • vim(1)
  • 正则表达式(1)
  • 分布式(1)
  • Linux环境编程(1)
  • 让你丫爬(1)
  • STL(7)
  • 数学(10)
  • shell脚本(1)
  • Linux驱动(1)
  • 网络(6)
  • 数据结构-算法(14)
  • Linux/UNIX系统编(1)
  • 未分配的博文(0)
  • 文章存档

    2019年(30)

    2018年(47)

    2017年(1)

    我的朋友

    分类: NOSQL

    2019-06-10 10:31:43

    ae_epoll,顾名思义,它底层的实现就是epoll(),相比于select(),epoll()的更加优秀,他会把就绪的描述符放到一个链表里面,并返回给调用者(具体是通过eventpoll来实现的,这个后续讲网络编程的时候会详细说下),省去了遍历时间。

     redis当中将epoll()封装如下:

    点击(此处)折叠或打开

    1. typedef struct aeApiState {
    2.     int epfd;
    3.     struct epoll_event *events;
    4. } aeApiState;
    一般api如下:

    点击(此处)折叠或打开

    1. static int aeApiCreate(aeEventLoop *eventLoop) {
    2.     aeApiState *state = zmalloc(sizeof(aeApiState));

    3.     if (!state) return -1;
    4.     state->events = zmalloc(sizeof(struct epoll_event)*eventLoop->setsize);
    5.     if (!state->events) {
    6.         zfree(state);
    7.         return -1;
    8.     }
    9.     state->epfd = epoll_create(1024); /* 1024 is just a hint for the kernel */
    10.     if (state->epfd == -1) {
    11.         zfree(state->events);
    12.         zfree(state);
    13.         return -1;
    14.     }
    15.     eventLoop->apidata = state;
    16.     return 0;
    17. }

    18. static int aeApiResize(aeEventLoop *eventLoop, int setsize) {
    19.     aeApiState *state = eventLoop->apidata;

    20.     state->events = zrealloc(state->events, sizeof(struct epoll_event)*setsize);
    21.     return 0;
    22. }

    23. static void aeApiFree(aeEventLoop *eventLoop) {
    24.     aeApiState *state = eventLoop->apidata;

    25.     close(state->epfd);
    26.     zfree(state->events);
    27.     zfree(state);
    28. }

    29. static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
    30.     aeApiState *state = eventLoop->apidata;
    31.     struct epoll_event ee = {0}; /* avoid valgrind warning */
    32.     /* If the fd was already monitored for some event, we need a MOD
    33.      * operation. Otherwise we need an ADD operation. */
    34.     int op = eventLoop->events[fd].mask == AE_NONE ?
    35.             EPOLL_CTL_ADD : EPOLL_CTL_MOD;

    36.     ee.events = 0;
    37.     mask |= eventLoop->events[fd].mask; /* Merge old events */
    38.     if (mask & AE_READABLE) ee.events |= EPOLLIN;
    39.     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
    40.     ee.data.fd = fd;
    41.     if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1;
    42.     return 0;
    43. }

    44. static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) {
    45.     aeApiState *state = eventLoop->apidata;
    46.     struct epoll_event ee = {0}; /* avoid valgrind warning */
    47.     int mask = eventLoop->events[fd].mask & (~delmask);

    48.     ee.events = 0;
    49.     if (mask & AE_READABLE) ee.events |= EPOLLIN;
    50.     if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
    51.     ee.data.fd = fd;
    52.     if (mask != AE_NONE) {
    53.         epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee);
    54.     } else {
    55.         /* Note, Kernel < 2.6.9 requires a non null event pointer even for
    56.          * EPOLL_CTL_DEL. */
    57.         epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee);
    58.     }
    59. }
    60. static char *aeApiName(void) {
    61.     return "epoll";
    62. }
    核心调用如下:

    点击(此处)折叠或打开

    1. static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
    2.     aeApiState *state = eventLoop->apidata;
    3.     int retval, numevents = 0;

    4.     retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,
    5.             tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
    6.     if (retval > 0) {
    7.         int j;

    8.         numevents = retval;
    9.         for (j = 0; j < numevents; j++) {
    10.             int mask = 0;
    11.             struct epoll_event *e = state->events+j;

    12.             if (e->events & EPOLLIN) mask |= AE_READABLE;
    13.             if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
    14.             if (e->events & EPOLLERR) mask |= AE_WRITABLE;
    15.             if (e->events & EPOLLHUP) mask |= AE_WRITABLE;
    16.             eventLoop->fired[j].fd = e->data.fd;
    17.             eventLoop->fired[j].mask = mask;
    18.         }
    19.     }
    20.     return numevents;
    21. }



    阅读(6166) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~
    评论热议
    请登录后评论。

    登录 注册