辅助说明:
1)select和poll每轮循环都需要将描述符和事件传给内核,而epoll每个描述符只需要传一次,不需要每轮都传,而且select事件集合相对较小
2)select和poll在内核中是以轮询的方式实现的,时间复杂度O(n),而epoll是采用回调函数的方式监测,时间复杂度为o(1)
3)select和poll返回后,为了找到就绪描述符,需要遍历所有元素,时间复杂度为O(n),而epoll直接拿到就绪描述符,不需要遍历所有元素,时间复杂度为O(1)。
那么epoll所解决的三个问题:
1)不用每次拷贝数据到内核中
2)注册回调函数的方式实现O(1)
3)只返回就绪的描述符O(1)
那么ET和LT模式的区别呢?
LT:事件就绪后,如果应用程序没有处理或者没有处理完,io函数会一直提醒,直到处理完成(阻塞和非阻塞)
ET:事件就绪后,io函数只提醒一次就不再提醒,所以应用程序必须一次将事件处理完成(只能非阻塞)
为何ET设置成非阻塞呢?
因为只提醒一次,不知道缓冲区有多少数据,所以必须设置成循环去读数据,但是循环读可能会发生阻塞
比如说缓冲区现在放了200个字节,第一次循环读取128个,那么第二次再去读取剩下的不会阻塞,但是如果一次性读取完了,第二次就会产生阻塞,所以ET需要设置成非阻塞的。