免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: 草中宝
打印 上一主题 下一主题

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

论坛徽章:
2
操作系统版块每日发帖之星
日期:2015-08-06 06:20:00IT运维版块每日发帖之星
日期:2015-08-15 06:20:00
11 [报告]
发表于 2009-12-14 13:15 |只看该作者
原帖由 6828 于 2009-12-14 06:16 发表
epoll的man中明确说明,close一个fd会导致此fd从epoll sets中移除。因此close一个fd之后,你不会在epoll_wait之后发现events中有这个fd。
一句话,直接close这个fd即可,其它的不用担心了。



服务端EPOLLET模式,是可以在其它的线程(check 线程)close fd,不过会在主线程激发EPOLLIN事件,主线程recv,errno返回EBADF(Bad file number),详见我第一段内容。就是这个错误很不爽,会造成无法区分EBADF(Bad file number)到底是不是真的有错误,还是因为别的线程close了fd之后造成的。

论坛徽章:
2
操作系统版块每日发帖之星
日期:2015-08-06 06:20:00IT运维版块每日发帖之星
日期:2015-08-15 06:20:00
12 [报告]
发表于 2009-12-14 13:20 |只看该作者
原帖由 benjiam 于 2009-12-14 10:49 发表
的确单线是不加锁的。 很多项目也是这么做的

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

假设 线程 1                                线程2
   

     find fd  超时

                                epol ...


按照这个逻辑,多线程的epoll,是有必要加锁的了。晚上回去测试下。

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


按这位老大的方法,加了互斥锁,不过发现还是没有用,主线程还是会收到 EPOLLIN ,主线程recv数据,接着报EBADF(Bad file number)错误。

论坛徽章:
2
操作系统版块每日发帖之星
日期:2015-08-06 06:20:00IT运维版块每日发帖之星
日期:2015-08-15 06:20:00
14 [报告]
发表于 2009-12-14 20:56 |只看该作者
原帖由 6828 于 2009-12-14 06:16 发表
epoll的man中明确说明,close一个fd会导致此fd从epoll sets中移除。因此close一个fd之后,你不会在epoll_wait之后发现events中有这个fd。
一句话,直接close这个fd即可,其它的不用担心了。


close是可以close,不过主线程就会收到 EPOLLIN ,主线程recv数据,接着报EBADF(Bad file number)错误,因为这个fd已经在check线程中被关闭了。如何识别出这个EBADF是因为自己在check线程中主动close掉而造成的?

论坛徽章:
0
15 [报告]
发表于 2009-12-14 22:45 |只看该作者
eventfd = pipe();
mutex_lock: lock;
socket_list:  list;

keepalive_routine:
{
      set timeout = check_interval
      set notify = false;
      getlock;
      set notify = true if exists timeout socket in socket_list;
      update timeout;
      unlock;
      if notify
        wakup_epoll;
      wait_timeout(timeout);
}

wakup_epoll:
{
   write 1 bytes to eventfd, this will force epoll_wait return.
}

epoll_routine:
{
    add  eventfd to epoll
again:
   if (eventfd is readable)
        read all bytes in eventfd
        getlock;
        remove and close timeout socket;
        unlock;
    epoll_wait;
    goto again;
}

[ 本帖最后由 pagx 于 2009-12-14 22:49 编辑 ]

论坛徽章:
2
操作系统版块每日发帖之星
日期:2015-08-06 06:20:00IT运维版块每日发帖之星
日期:2015-08-15 06:20:00
16 [报告]
发表于 2009-12-14 23:44 |只看该作者
谢谢 pagx ,看明白上面伪代码的意思了。这个思路确实好

非常感谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP