免费注册 查看新帖 |

Chinaunix

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

如何识别server端程序自己close socket的EPOLLIN? [复制链接]

论坛徽章:
2
操作系统版块每日发帖之星
日期:2015-08-06 06:20:00IT运维版块每日发帖之星
日期:2015-08-15 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-13 13:21 |只看该作者 |倒序浏览
服务端EPOLLET模式,两个线程,主线程和socket check线程。socket check线程的作用是检查心跳包的时间,如果心跳包超时,则主动close对应的socket,而不管这个socket是否还没关闭,这时将会触发主线程的EPOLLIN事件。主线程recv,errno返回EBADF(Bad file number)。请问对于主线程的EPOLLIN事件,怎样才可以识别是因为自己close socket引起的?


socket check线程 部分代码

struct epoll_event ev;
epoll_ctl(p->kdpfd, EPOLL_CTL_DEL, p->sockfd, &ev);
close (p->sockfd);//就是这里引起主线程的EPOLLIN事件

[ 本帖最后由 草中宝 于 2009-12-13 13:22 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-12-13 13:32 |只看该作者
你有加锁吗? 没有的话, 还有 可能引起close 2次的问题。
加了锁 性能下降。可以解决所有问题 就这么简单

论坛徽章:
2
操作系统版块每日发帖之星
日期:2015-08-06 06:20:00IT运维版块每日发帖之星
日期:2015-08-15 06:20:00
3 [报告]
发表于 2009-12-13 13:46 |只看该作者
原帖由 benjiam 于 2009-12-13 13:32 发表
你有加锁吗? 没有的话, 还有 可能引起close 2次的问题。
加了锁 性能下降。可以解决所有问题 就这么简单


对于socket本身,就是上面的p->sockfd,程序里是没有加锁的。对于socket队列,就是socket check线程要检查的,倒是加锁了。

请问下benjiam,socket本身也要加锁?怕两个线程同时操作同一个socket?

论坛徽章:
0
4 [报告]
发表于 2009-12-13 13:53 |只看该作者
先唤醒 epoll_wait, 然后再close, 不过会产生线程撤换,效率会慢一些。或者你可以把 close调用放到 epoll_wait 线程去。 check 这边只负责通知。

论坛徽章:
2
操作系统版块每日发帖之星
日期:2015-08-06 06:20:00IT运维版块每日发帖之星
日期:2015-08-15 06:20:00
5 [报告]
发表于 2009-12-13 14:03 |只看该作者
原帖由 pagx 于 2009-12-13 13:53 发表
先唤醒 epoll_wait, 然后再close, 不过会产生线程撤换,效率会慢一些。或者你可以把 close调用放到 epoll_wait 线程去。 check 这边只负责通知。


能说说怎么唤醒 epoll_wait吗?还有check 这边怎么可以负责通知到主线程?在epoll_wait这边close也是一个方法。

我对epoll不是很熟悉,见笑了。

才发现pagx也是广西的,我贺州的,MSN gpsoracle*hotmail.com 有空聊聊。

论坛徽章:
2
操作系统版块每日发帖之星
日期:2015-08-06 06:20:00IT运维版块每日发帖之星
日期:2015-08-15 06:20:00
6 [报告]
发表于 2009-12-13 20:53 |只看该作者
老大们指点下吧。

论坛徽章:
0
7 [报告]
发表于 2009-12-14 06:16 |只看该作者
epoll的man中明确说明,close一个fd会导致此fd从epoll sets中移除。因此close一个fd之后,你不会在epoll_wait之后发现events中有这个fd。
一句话,直接close这个fd即可,其它的不用担心了。

论坛徽章:
0
8 [报告]
发表于 2009-12-14 06:19 |只看该作者
原帖由 benjiam 于 2009-12-13 13:32 发表
你有加锁吗? 没有的话, 还有 可能引起close 2次的问题。
加了锁 性能下降。可以解决所有问题 就这么简单


一般epoll的应用都不加锁吧?一旦一个mutex停在那了,整个应用就被hang了

论坛徽章:
0
9 [报告]
发表于 2009-12-14 10:49 |只看该作者
的确单线是不加锁的。 很多项目也是这么做的

但是如果你采用多线是会有问题的

假设 线程 1                                线程2
   

     find fd  超时

                                epoll_wait 返回
                                epoll_IN  
                                                read  len = 0
                                                所以close fd
                                 
    close fd


这个时候就会出现fd 被关闭2次的情况。

论坛徽章:
0
10 [报告]
发表于 2009-12-14 12:54 |只看该作者
原帖由 6828 于 2009-12-14 06:16 发表
epoll的man中明确说明,close一个fd会导致此fd从epoll sets中移除。因此close一个fd之后,你不会在epoll_wait之后发现events中有这个fd。
一句话,直接close这个fd即可,其它的不用担心了。


多线程下,这个处理方式应该是不确定的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP