【Linux】了解I/O复用的LT模式和ET模式

LT模式和ET模式

1、LT模式:内核如果检测就绪事件并将其通知给应用程序后,应用程序可以不立即处理该事件,因为下次调用epoll _wait时,还会将此事件通知给应用程序。
2、ET模式:内核如果检测就绪事件并将其通知给应用程序后,应用程序必须立即处理该事件,否则下次调用epoll wait时,不会将此事件再通知给应用程序
3、select和poll只能工作在LT模式下,epoll支持高效的ET模式

实例说明

1、epoll在默认情况下是LT模式,如果想要让他支持ET模式,可以在获取新连接的代码下在事件类型中加上EPOLLET。
在这里插入图片描述
2、LT模式下
在每次处理客户端发过来的数据时,将每次读取数据的长度设置为5,运行结果为:
在这里插入图片描述
原因是:同一个事件,虽然只发了一次数据,但是这个事件将epoll_wait触发了三次。
3、ET模式下(加上EPOLLET后)
文件描述符是以ET模式来处理的。
在这里插入图片描述
4、ET模式下如何处理就绪的事件?
因为要求应用程序必须立即处理并且处理完该事件,所以必须要用while(1)去处理
存在问题:
(1)如何判断已经将本次的事件处理完成。
解决方法:recv返回值如果是-1,并且判断全局的errno。

用返回值来判断文件读取是否完成。但是用recv处理时,如果用它来操作具体的客户端链接文件描述符,它本身是会阻塞的,如果阻塞了,是无法判断的。
(2)为了解决recv阻塞问题,可以使得recv操作accept返回的文件描述符时以非阻塞方式处理。用fcntl()方法

epoll的EPOLLONESHOT事件

前言

一个线程在读取完某个socket上的数据后开始处理这些数据,而在数据的处理过程中该socket上又有新数据可读(EPOLLIN再次被触发),此时另外一个线程被唤醒来读取这些新的数据。于是就出现了两个线程同时操作一个socket的局面。但是我们期望的是一个socket连接在任一时刻都只被一个线程处理。这一点可以使用epoll的EPOLLONESHOT事件实现。

概念

1、EPOLLONESHOT事件的文件描述符注册后,操作系统最多触发其上注册的一个可读、可写或者异常事件,且只触发一次,除非我们使用epoll _ctl 函数重置该文件描述符上注册的EPOLLONESHOT事件。
2、注册了EPOLLONESHOT事件的socket一旦被某个线程处理完毕,该线程就应该立即重置这个socket上的EPOLLONESHOT事件,以确保这个
socket下一次可读时,其EPOLLIN事件能被触发
,进而让其他工作线程有机会继续处理这个socket。
3、尽管一个 socket在不同时间可能被不同的线程处理,但同一时刻肯定只有一个线程在为它服务。这就保证了连接的完整性,从而避免了很多可能的竞态条件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值