select/epoll模型

select和epoll都是多路复用的实现。

select

调用select(fds),把fds(最多1024个)从用户空间拷贝到内核空间,进程阻塞,

当socket缓冲区有数据,唤醒进程,遍历fds,处理。

epoll

epoll_create在内核空间创建eventpoll对象(包括红黑树和就绪链表),

调用epoll_clt(fds)把fds加入到eventpoll的红黑树中,

给每个fd都向底层注册回调,

调用epoll_wait,进程阻塞,

当socket缓冲区有数据时,通过回调把红黑树对应的fd加入到就绪链表,

epoll_wait就会得到就绪链表中就绪的fds,处理。

epoll水平触发(LT)和边缘触发(ET)的区别

select/epoll模型
//水平触发
ret = read(fd, buf, sizeof(buf));

//边缘触发
while(true) {
    ret = read(fd, buf, sizeof(buf);
    if (ret == EAGAIN) break;
}
View Code

水平触发(LT):只要缓冲区有数据,就会触发(epoll_wait结束阻塞得到就绪列表),是默认模式。(select也是水平触发)

边缘触发(ET):只有新数据到达缓冲区才会触发,不管缓冲区有无旧数据。

实现:LT模式每次把就绪链表清空,下次有新数据到来才会调用回调把新数据的fd加入到就绪链表中。

    ET模式则不会把还有数据的fd从就绪链表删掉,所以下次调epoll_wait还会触发。

因此,ET模式实际上把保证数据处理完的逻辑交给了用户,只会触发一次所以提高了效率。

-----

参考

https://bbs.gameres.com/thread_842984_1_1.html

https://blog.csdn.net/daaikuaichuan/article/details/83862311

https://www.cnblogs.com/guxuanqing/p/10570625.html

上一篇:面试中的 IO 多路复用


下一篇:I/O复用----poll