socket在epoll两种工作模式下注册事件的工作原理是怎样的?

发布于 2021-11-29 13:41:46 字数 251 浏览 783 评论 13

1.LT是epoll缺省的工作方式,同时支持blocking和nonblocking socket

通常的NIO framework均要把socket设置为nonblocking,blocking是用在什么场景下使用?

2.ET仅支持nonblocking socket,为什么?

java中的selector对于linux而言底层实现为epoll的LT模式,为什么不提供ET模式?

@乌龟壳,@中山野鬼

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

筱武穆 2021-11-30 02:08:20

bingo

回眸一笑 2021-11-30 02:08:19

@乌龟壳 ,对于ET模式不能设置阻塞,是由于很大程度上可能是因为在改模式下需要处理读到空,写到满;如果是阻塞的,这个时候导致线程阻塞在读写而不是epoll_wait了,进而无法处理其他socket,标准答案应该加上你下面的部分

如日中天 2021-11-30 02:08:17

blocking 和时序有关。nonblocking强调并发。 java的不懂。哈。

刘备忘录 2021-11-30 02:08:09

java 实现NIO也是需要底层系统支持的,但是它愿意支持多少,对于java程序员来说才能用多少

爱的那么颓废 2021-11-30 02:08:05

回复
性能和底层有关系,但JAVA的API到底是LT还是ET是java自己实现的,就算java底层用ET(其实甚至不一定是epoll,iocp没有et这个概念),java照样可以实现成LT。java有自己的缓冲区,这个API完全可以独立实现逻辑。

奢华的一滴泪 2021-11-30 02:07:29

java里怎么做,是java的API实现的逻辑,和epoll不是一个层面的事情。

别再吹冷风 2021-11-30 02:07:04

补充,ET为了把缓冲区读完,使用nonbloking可以做到在缓冲区空的时候返回一个缓冲区空的标志EAGAIN,如果使用blocking就在缓冲区空的时候直接阻塞了。后者并不是我们期望的执行效果,严格的异步程序只有调用epoll等待事件时允许阻塞,其它时候都要尽可能高效地使用CPU而不能作IO等待等。

EAGAIN The file descriptor fd refers to a file other than a socket and has been marked nonblocking (O_NONBLOCK), and the read would block.

但是如果我们可以得到缓冲区的实际大小,那用blocking严格只读取缓冲区大小的数据也是不会阻塞的,这个API没接触过,应该有,不过没必要这样去做,对性能是一种浪费。

写也是这样,以此类推。

把昨日还给我 2021-11-30 02:06:08

blocking socket也是可以注册LT 模式下epoll的

白龙吟 2021-11-30 02:05:31

第一个问题是阻塞和非阻塞网络编程的应用场景吧,前者的优势是简单方便好控制,转载下:

"阻塞模式,常见的通信模型为多线程模型,服务端accept之后,对每个socket创建一个线程去recv。逻辑上简单,适用于并发量小(客户端数目少),连续传输大数据量的情况下,比如文件服务器。还有就是在客户端recv服务器消息的时候也经常用,因为客户端就一个socket,用阻塞模式不影响效率,而且编程逻辑上要简单得多。

非阻塞模式,常见的通信模型为select模型和IOCP模型。适用于高并发,数据量小的情况,比如聊天室。客户端多的情况下,如果采用阻塞模式,需要开很多线程,影响效率。另外,客户端一般不采用非阻塞模式。"

拍不死你 2021-11-30 02:05:10

所以java的意思是如果你用到性能要求这么高情况,臣妾做不到,你换c去吧

后知后觉 2021-11-30 02:01:39

2.   主要是因为性能效率没有相差很大的情况下, 使用edge-trigger比level-trigger逻辑更复杂,出错概率更高,编程要求也高。

平定天下 2021-11-30 02:00:22

回答的很棒

做个少女永远怀春 2021-11-30 00:19:11

我的理解是,blocking和nonblocking和epoll是没有关系的。

epoll提供的是对socket收发缓冲区状态变更的通知,可读、可写、异常、已连接等的通知事件。

blocking和nonblocking是针对readwrite等函数在缓冲区满后,是否阻塞等待缓冲区有空间再执行下去的配置。

LT和ET只是通知方式不同,LT只要状态处于程序所关心的状态(可读,可写等),就发出通知。ET是只有状态发生变化后(接收缓冲区增加了数据,发送缓冲区减少了数据等)才通知。

所以写LT的程序,可以不一次性把缓冲区都处理完成,剩下的内容可以等下一轮事件循环处理,但写ET的程序就必须一次性把缓冲区的数据都处理完,不然下次只要缓冲区不变化就不通知,这样有可能有些数据就没有来得及处理。

例如缓冲区有数据:012345

使用LT处理:01—23—45,“—”代表下一次事件循环

错误使用ET:01—停住了,除非缓冲区又来了67

正确使用ET:012345—下一次通知

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文