【博客16】epoll 边缘触发模式下的 "陷阱"

内容: 在学习epoll的时候,知道了epoll的边缘与水平触发模式是各有用处的,并不是说什么情况下都是盲目用边缘,而且对文件描述符要不要设置成阻塞的也有很大关系,接下来先来看下epoll边缘模式下如果处理不当,没有加其他的措施,那么会导致客户端连接不上的情况。

测试代码:
【博客16】epoll 边缘触发模式下的 "陷阱"
【博客16】epoll 边缘触发模式下的 "陷阱"
【博客16】epoll 边缘触发模式下的 "陷阱"
【博客16】epoll 边缘触发模式下的 "陷阱"
【博客16】epoll 边缘触发模式下的 "陷阱"
【博客16】epoll 边缘触发模式下的 "陷阱"
【博客16】epoll 边缘触发模式下的 "陷阱"
开始测试:
1.启动服务端:
【博客16】epoll 边缘触发模式下的 "陷阱"
2.启动两个客户端去连接(打开两个终端,使用nc指令连接,然后发消息)
【博客16】epoll 边缘触发模式下的 "陷阱"
【博客16】epoll 边缘触发模式下的 "陷阱"
结果分析:epoll边缘模式下,由于每次来的消息如果你不一次性处理完的话,下一次就不通知你了,代码中sleep保证两次连接能够在同一次epoll_wait,否则的话,由于自己模拟不出高并发情况,那么自己手动连接肯定是没有epoll处理速度快的。在结果中可以看到第一次连接后,你发消息会有回复,但是第二次连接的,由于epoll返回,但accept只能完成一个连接,后面的就没有办法连接上来。所以对监听描述符,如果是边缘状态,没有用while一次性全部接收的话,会出现连接不上的情况,但是如果用while来接收,那最后一次读完后就阻塞了。所以重要的还有一个就是文件描述符要设置成非阻塞才能配合使用,因为如果设置成阻塞,那最后一次读完后,不就阻塞在那里了吗?对监听描述符用水平触发的话,就不会有这个问题,连接不上的客户,下一次epoll还会通知的。

建议:
1.对于监听的sockfd,最好使用水平触发模式,边缘触发模式会导致高并发情况下,有的客户端会连接不上。如果非要使用边缘触发,要用while来循环accept(),记得设置非阻塞io

2.对于connfd,边缘触发模式下,必须使用非阻塞IO,并要一次性全部读写完数据

3.对于connfd,水平触发模式下,阻塞非阻塞应该一样,因为既然epoll_wait能返回就一定是有数 据,不会阻塞的。