当你偶尔发现语言变得无力时,
不妨安静下来,
让沉默替你发声。
--- 里则林 ---
poll 的优点(和 select 的缺点对应)
网上说:epoll 中使用了内存映射机制
这种说法是不准确的。我们定义的 struct epoll_event
是我们在用户空间中分配好的内存。势必还是需要将内核的数据拷贝到这个用户空间的内存中的。
可以这么说epoll几乎没有缺点!
select、poll、epoll都存在一个现象:当有事件就绪时,用户不处理就会一直通知用户处理,循环打印日志信息。
EPOLL的工作模式有两种:
上面现象是LT模式下的产物,那么怎么理解LT与ET呢?我们通过快递小哥的例子进行讲解:
有两名快递员张三李四,他们一个温和老实,一个严肃霸道。 小明前几天买了5个包裹,今天一起送到了快递站。张三李四分别分到了小明的3个包裹和2个包裹。 张三首先到达了小王所在的小区,他给该小区所以的收件人都打了一遍电话:“请你下来拿快递”。小明这时正在和舍友打无畏契约,拿不了快递。过了一会张三再次给小明打电话让他下来拿快递,小明下去取了一个就立马回去了。张三一看,还有两个包裹啊,于是又给小王打电话!这时李四过来了,把两个快递交给了张三。张三就在这里一直打电话 第二天,又有小明的5个包裹,这次李四来到小区门口,开始打电话:我只给你打一次电话,你有快递到了,不拿我就走人。小明一听,这快递小哥这么硬气,哎我就不拿,那你怎么办。于是小明就没有去拿,结果李四真的走了。一会碰到了张三,张三把小明的包裹给了李四,于是李四又来到小区门口,再一次强硬的打电话。小明决定去拿了,快递不拿他是真走啊!
这里我们可以总结出来:
在这个例子中,快递就是数据,张三对应LT水平触发模式,李四对应ET边缘触发模式。一般情况下是LT水平触发模式。
这两种模式哪一个更加高效呢?ET模式更加高效!毕竟李四比张三打的电话少的多得多!
LT水平触发是默认的,那么一个如何设置成ET边缘触发模式呢?
假如服务端使用ET模式,这时服务端需要的数据是10K,客户端将这10K数据发过来,服务端第一次只读取了1K的数据。由于是ET模式,在客户端发送新的数据之前,服务端一直不会进行读取!所以ET模式下,必须一次性将数据读完,就要进行循环读取直到读取不到!这样也就必须使用非阻塞的读取了(才能支持循环读取)!LT模式没有这种问题。
那么LT设置成非阻塞呢?那么是不是和ET模式一样了呢?所以一般不能说ET模式一定比LT模式的效率更高。可是,ET强制程序员必须使用非阻塞进行读取!LT不会强制程序员使用非阻塞读取!所以可以认为ET模式更加高效!