epoll:Linux系统独有的
select:fd_set;
poll:struct pollfd fds[];
select和poll都是用户态存在,每一次调用select或者poll,都会存在两次数据拷贝,一次是在调用时,一次是在返回时。用户程序检索就绪事件的时间复杂度为O(n)。
epoll:用户程序检索就绪事件的时间复杂度为O(1)。
1 | //创建内核事件表(用户关注的所有文件描述符以及关注的事件类型) |
客户端
1 |
|
服务端
1 |
|
通信测试
不知道为啥在deepin系统下跑不出来,在centos下可以跑出来
LT和ET模式
LT模式是默认的工作模式,也就是上面的代码,但是ET模式是epoll的高效工作模式。对于ET模式的文件描述符,当epoll_wait检测到有事件发生时并将此事件通知应用程序后,应用程序必须立即处理该事件,因为后续的epoll_wait调用将不再向应用程序通知这一事件。所以ET模式很大程度降低了同一个epoll事件被重复触发的次数,因此ET模式比LT模式工作效率高。
LT代码
1 |
|
ET代码
1 |
|
从图中可以看出只收到了一个字母,但是LT却接受了好几次来接受完整个数据。但是ET再次发送时,服务器却接受了上次发送端第二个字母,所以发送的数据全都在接收缓冲区存着。
那么怎么解决这个问题呢
改进的ET代码
1 |
|
测试
发一次之后全部接收完