免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: wyezl

epoll模型的使用及其描述符耗尽问题的探讨 [复制链接]

论坛徽章:
0
发表于 2006-09-03 00:16 |显示全部楼层
原帖由 solegoose 于 2006-9-1 10:13 发表
我认为原因是没有对每个FD进行超时的管理.
假设下列情况,一用户发起连接,服务器accept成功,返回了FD,但是在用户发起请求前,如果网络有问题,此FD当然无法返回POLLIN,当然就不会有POLLOUT等等了,这样FD就无法关闭. ...



KEEPALIVE,socket选项.怎么用?
能直接设置超时时间和自动回收吗?

论坛徽章:
0
发表于 2006-09-04 09:35 |显示全部楼层
原帖由 solegoose 于 2006-9-1 10:13 发表
我认为原因是没有对每个FD进行超时的管理.
假设下列情况,一用户发起连接,服务器accept成功,返回了FD,但是在用户发起请求前,如果网络有问题,此FD当然无法返回POLLIN,当然就不会有POLLOUT等等了,这样FD就无法关闭. ...


无法返回POLLIN,那为什么也 不返回 EPOLLERR | EPOLLHUP呢?

论坛徽章:
0
发表于 2006-09-04 09:46 |显示全部楼层
怎么设置KEEPALIVE,请参考《UNIX网络编程卷1》第七章。
能否返回POLLERR这个我不是很确定,我对epoll不是很熟悉。但是在对方主机突然崩溃或者网络突然断开的时候,因为来不及有数据包的交换,估计epoll不容易探测到此连接有问题,在这种情况下,就是调用write,都能马上成功返回。

论坛徽章:
0
发表于 2006-09-04 18:33 |显示全部楼层
原帖由 solegoose 于 2006-9-4 09:46 发表
怎么设置KEEPALIVE,请参考《UNIX网络编程卷1》第七章。
能否返回POLLERR这个我不是很确定,我对epoll不是很熟悉。但是在对方主机突然崩溃或者网络突然断开的时候,因为来不及有数据包的交换,估计epoll不容易探 ...


关于KEEPALIVE我了解了一下,那个需要两个小时,还要发送9个分节。
我觉得这用于web server不太合适吧。

论坛徽章:
0
发表于 2006-09-06 14:07 |显示全部楼层
在computer_xu的BLOG  http://blog.sina.com.cn/u/544465b0010000bp
中看到了如下翻译。也贴在这。


在man epoll中的Notes说到:

EPOLL事件分发系统可以运转在两种模式下:
   Edge Triggered (ET)
   Level Triggered (LT)
接下来说明ET, LT这两种事件分发机制的不同。我们假定一个环境:
1. 我们已经把一个用来从管道中读取数据的文件句柄(RFD)添加到epoll描述符
2. 这个时候从管道的另一端被写入了2KB的数据
3. 调用epoll_wait(2),并且它会返回RFD,说明它已经准备好读取操作
4. 然后我们读取了1KB的数据
5. 调用epoll_wait(2)......

Edge Triggered 工作模式:
如果我们在第1步将RFD添加到epoll描述符的时候使用了EPOLLET标志,那么在第5步调用epoll_wait(2)之后将有可能会挂起,因为剩余的数据还存在于文件的输入缓冲区内,而且数据发出端还在等待一个针对已经发出数据的反馈信息。只有在监视的文件句柄上发生了某个事件的时候 ET 工作模式才会汇报事件。因此在第5步的时候,调用者可能会放弃等待仍在存在于文件输入缓冲区内的剩余数据。在上面的例子中,会有一个事件产生在RFD句柄上,因为在第2步执行了一个写操作,然后,事件将会在第3步被销毁。因为第4步的读取操作没有读空文件输入缓冲区内的数据,因此我们在第5步调用epoll_wait(2)完成后,是否挂起是不确定的。epoll工作在ET模式的时候,必须使用非阻塞套接口,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死。最好以下面的方式调用ET模式的epoll接口,在后面会介绍避免可能的缺陷。
   i    基于非阻塞文件句柄
   ii   只有当read(2)或者write(2)返回EAGAIN时才需要挂起,等待

Level Triggered 工作模式
相反的,以LT方式调用epoll接口的时候,它就相当于一个速度比较快的poll(2),并且无论后面的数据是否被使用,因此他们具有同样的职能。因为即使使用ET模式的epoll,在收到多个chunk的数据的时候仍然会产生多个事件。调用者可以设定EPOLLONESHOT标志,在epoll_wait(2)收到事件后epoll会与事件关联的文件句柄从epoll描述符中禁止掉。因此当EPOLLONESHOT设定后,使用带有EPOLL_CTL_MOD标志的epoll_ctl(2)处理文件句柄就成为调用者必须作的事情。

以上翻译自man epoll.

然后详细解释ET, LT:

LT(level triggered)是缺省的工作方式,并且同时支持block和no-block socket.在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表.

ET(edge-triggered)是高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如,你在发送,接收或者接收请求,或者发送接收的数据少于一定量时导致了一个EWOULDBLOCK 错误)。但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only once),不过在TCP协议中,ET模式的加速效用仍需要更多的benchmark确认。

在许多测试中我们会看到如果没有大量的idle-connection或者dead-connection,epoll的效率并不会比select/poll高很多,但是当我们遇到大量的idle-connection(例如WAN环境中存在大量的慢速连接),就会发现epoll的效率大大高于select/poll。

论坛徽章:
0
发表于 2006-09-10 19:37 |显示全部楼层

回复 10楼 playmud 的帖子

ret = recv(cfd, buffer, sizeof(buffer),0);

这里应该判断一下状态吧,如果对方网络这个时候断开,你这边就不会关闭连接.

论坛徽章:
0
发表于 2006-09-11 18:18 |显示全部楼层
原帖由 realclimber 于 2006-9-10 19:37 发表
ret = recv(cfd, buffer, sizeof(buffer),0);

这里应该判断一下状态吧,如果对方网络这个时候断开,你这边就不会关闭连接.



我在实际的程序中做了些简单的判断。
这是个最初的演示版本,所以有些没写上。

论坛徽章:
0
发表于 2006-09-15 22:34 |显示全部楼层
现在到底是什么问题?

论坛徽章:
0
发表于 2006-09-19 10:59 |显示全部楼层
问题还是没有解决吗?
楼主有没有采用其他的变通做法?

论坛徽章:
0
发表于 2006-09-19 11:11 |显示全部楼层
没想到更好的办法,只有一个监视线程。定期关闭一些超时的fd。
估计这是不可避免的了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP