打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【2019-11-07】twemproxy事件--by 闫昌

epoll简介:

函数:epoll_create;、epoll_ctl;、epoll_wait;

epoll_create(size);//size 低版本生效,高版本不生效

epoll 的LT模式

水平触发模式,epoll_wait的处理流程为:遍历就绪的链表,把fd的buf中有数据的fd返回给用户,并在链表中保留该节点,buf中没数据的则从链表中剔除,放回红黑树中,这么做的好处是,只要fd中海油未处理的数据,都会通过epoll_wait读取到,缺点是,每次需遍历,性能差。

epoll的EL模式
边缘触发模式,epoll_wait就非常简单,返回链表中所有的fd给用户,并情况就绪列表,放回红黑树中,等待新事件到来。好处就是性能高,缺点是,用户拿到fd后读取其数据时每次没读取完,造成事件的丢失。

twemproxy对事件的使用

twemproxy对epoll/kqueue/evport进行了统一封装,一般linux使用epoll, mac使用kqueue,Sun Solaris使用evport,为了统一底层api调用,对上面的三种事件处理api进行了接口的统一: event/nc_event.h

相关结构体

struct event_base {     int   ep;  /* epoll descriptor */     struct epoll_event *event; /* event[] - events that were triggered */     int    nevent; /* # event */     event_cb_t   cb; /* 回调函数event callback */     };

事件处理核心api参考:

  • event_base_create()    创建事件循环管理fd
event_base_create(int nevent, event_cb_t cb){   ep = epoll_create(nevent);   event = nc_calloc(nevent, sizeof(*event));   evb = nc_alloc(sizeof(*evb));   evb->ep = ep;   evb->event = event;   evb->nevent = nevent;   evb->cb = cb;}
  • event_add_in()             将一个fd的读事件纳入事件管理器的管理中
event_add_in(struct event_base *evb, struct conn *c){  struct epoll_event event;  int ep = evb->ep;  event.events = (uint32_t)(EPOLLIN | EPOLLET);//ET模式  status = epoll_ctl(ep, EPOLL_CTL_MOD, c->sd, &event);}
  • event_add_out()           将一个fd的读写事件纳入事件管理器的管理中
event_add_out(struct event_base *evb, struct conn *c){  struct epoll_event event;  int ep = ev->ep;  event.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);  status = epoll_ctl(ep, EPOLL_CTL_MOD, c->sd, &event);}
  • event_add_conn()        将一个fd的读写事件纳入事件管理器的管理中
event_add_conn(struct event_base *evb, struct conn *c){   struct epoll_event event;   int ep = evb->ep;   event.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);   event.data.ptr = c;   status = epoll_ctl(ep, EPOLL_CTL_ADD, c->sd, &event);}
  • event_wait()                  从事件管理器中获取准备好读/写的fd列表,并调用cb进行处理
event_wait(struct event_base *evb,int timeout)//自己封装的epoll_wait{ struct epoll_event event; int nevent = evb->nevent; for(;;) {   int i, nsd;   nsd = epoll_wait(ep, event, nevent, timeout);   for(i =0; i < nsd; i++) {    struct epoll_event *ev = &evb->event[i];    uint32_t events =0;    if(ev->events & (EPOLLIN | EPOLLHUP))    {        events |= EVENT_READ;    }    if(ev->events & EPOLLOUT) {        events |= EVENT_WRITE;    }    if(evb->cb != NULL) {        evb->cb(ev->data.ptr, events);//执行回调函数 cb是在 event_base_create添加     }   }  }}

怎么用:

todo

负载均衡算法

redis协议的解析

多个redis命令在一起怎么处理,粘包问题

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【Jabberd2源码剖析系列 mio】
带有边缘触发和单触发的Epoll仅报告一次
C10k问题
【原创】技术系列之 网络模型(三)多路复用模型
epoll()实现分析
epoll函数
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服