免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 10184 | 回复: 11
打印 上一主题 下一主题

求教:epoll的ET模式对EPOLLOUT事件怎么处理的? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-07-28 15:59 |只看该作者 |倒序浏览
以前写过一个epoll LT模式的网游服务器的socket通信架构;

据说ET模式在大连接情形下更高效,但是更难用;


LT似乎是关注资源,ET关注事件;

只要资源还有,LT就会通知你;

只要新资源到达,ET也会通知你;但是如果你不用完,又没有新资源到达,就不再理你了。剩下的资源。。浪费着。。


关于recv的两种方式处理还是很好理解;


但是至今没想通关于send的处理;

因为linux下有个“bug”,epoll对EPOLLOUT事件总会返回真(只要你的内核发送缓冲区有1个字节的空间)。

不知道该怎么处理。。。

求解。。。

论坛徽章:
0
2 [报告]
发表于 2010-07-28 16:01 |只看该作者
本帖最后由 okocha-jay 于 2010-07-28 16:13 编辑

最近因为服务器移植到linux,正好想重新改一下。

网上找的
With EPOLLET, EPOLLOUT will be triggered once at the start, and never again
until after you've filled the send buffer and a send would block, and some room
comes available again.

可是我测得ET模式下,只要EPOLLIN了,OUT也为真...

论坛徽章:
0
3 [报告]
发表于 2010-07-28 16:38 |只看该作者
我是这样做的,给每个连接一个bool记录是否可写,初始值为true。每次write的时候看能不能把待发送的数据发完,能的话就认为该连接还是可写的,如果不能发完那么就认为内核的缓冲区已经满了,记录为不可写。当触发out事件时就再尝试一下write,然后再根据write结果更新是否可写的bool。只要把fd设置为非阻塞的就可以了,最多就是多了几次无效的write尝试而已。

论坛徽章:
0
4 [报告]
发表于 2010-07-28 16:57 |只看该作者
以前写过一个epoll LT模式的网游服务器的socket通信架构;

据说ET模式在大连接情形下更高效,但是更难用 ...
okocha-jay 发表于 2010-07-28 15:59



    ET模式下,epoll理论上是当发送缓冲区由满变为不满,即有空闲空间了,会触发EPOLLOUT事件,但正如你所说“linux下有个“bug”,epoll对EPOLLOUT事件总会返回真(只要你的内核发送缓冲区有1个字节的空间)。”,我的做法是把fd放到可写队列中,如果fd已经在这个队列中则不重复放,如果没有在这个队列中(由满变为不满时),则放入这个队列,另外一个任务去读取这个队列,操作send

论坛徽章:
0
5 [报告]
发表于 2010-07-28 17:06 |只看该作者
如果就绪
写到EAGAIN
读到EAGAIN

论坛徽章:
0
6 [报告]
发表于 2010-07-28 22:26 |只看该作者
谢谢楼上各位的解答

不过我很纳闷的是,ET监视IN 和OUT事件,为什么IN事件到达时,会连带着一个OUT事件?感觉莫名其妙。除了连接刚建立时,之后都是成对出现IN/OUT事件

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
7 [报告]
发表于 2010-07-29 08:34 |只看该作者
ET时有IN事件发生时,这时一般都可以写,“顺便”就把可写事件带回来了,大概设计者觉得虽然是ET,多给事件总不会有错

论坛徽章:
0
8 [报告]
发表于 2010-07-29 09:15 |只看该作者
ET时有IN事件发生时,这时一般都可以写,“顺便”就把可写事件带回来了,大概设计者觉得虽然是ET,多给事件 ...
hellioncu 发表于 2010-07-29 08:34



    确实是这样,内核代码这块有注释就是说的这个意思

论坛徽章:
0
9 [报告]
发表于 2010-07-29 10:14 |只看该作者
多给事件,造成了一些额外处理,真的还不如不给,我认为这是个bug

论坛徽章:
0
10 [报告]
发表于 2010-07-29 10:35 |只看该作者
谢谢楼上各位说明。原来又是一个“bug”呵呵。

另:
为什么非阻塞socket,send也会阻塞?
A端发数据,B端不调用recv;
于是一会儿A端的发送缓冲区满了,竟然阻塞在send调用;而不是返回-1和EAGAIN?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP