Epoll 小结(Nginx)

1. 数据结构

//表示一个要监听的事件
//其中events表示监听的标志位 EPOLLIN  EPOLLOUT
//表示被触发后的data
struct epoll_event{
    uint32_t events;
    epoll_data_t data;
}
//其中只有ptr数据结构比较重要
typedef union epoll_data{
    void *ptr;
    int fd;
}

在nginx的实现,

struct epoll_event e;//定义需要监听的事件
e.events = 传进来的值 ;//用来表示监控输入还是输出
e.data.ptr = connection;//当有事件触发时,获取得到data.ptr从而得到连接

2. epoll create/close

int epoll_create(int size)// size预估事件多少
                          // 返回epoll的fd

epoll_close(efd);

3. 添加事件

int epoll_ctr(int efd, int op, int fd , struct epoll_event *event)
//efd 由epoll_create创建的fd
//op  分为3种操作,EPOLL_CTL_ADD EPOLL_CTL_MOD EPOLL_CTL_DEL
//event 添加需要监控的事件, 数据结构如上。

4. 监听事件

int epoll_wait(int efd, struct epoll_event *event, int maxeevents, int timeout)
//efd 由epoll_create创建的fd
//timeout 为一次监听的间隔
//当有事件触发 返回int 表示事件个数,event里存储的是触发的事件

5. LT && ET
LT 当缓冲区还有数据时会一直触发,支持阻塞和非阻塞两种
ET 只触发有数据那一次,只支持非阻塞
如果为非阻塞则需要

// 设置events 为ET
ep_event.events |= EPOLLET
// 获取得到原来的fd, 加上O_NONBLOCK
int old_flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, old_flags | O_NONBLOCK);

在nginx的中用到了这样的一个原理
不管在32bit 和 64bit机器上,指针的最后一位都是0, 在事件触发之后, 先通过 e.data.ptr得到conn的指针,指针的最后一位有个instance,指针的read 或者 write中有个instance,两个instance 来对比,一致表示是有效连接

发布了46 篇原创文章 · 获赞 1 · 访问量 1万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章