自己曾经做一个接口server时候,这样的场景下我的设计是多个线程操作同一个epoll fd。彼时,我的理由是epoll的系列函数是线程安全的。

当然有人不理解为什么会有多个线程操作同一个epoll fd的情形,这里略微铺陈一下接口server的场景。epoll fd有线程1维护。监听服务端port的socket的accept出来的acceptor(即新的socket fd)也放在这个epoll fd中。当收到client链接请求时候,线程2从连接池connector pool中挑选出来一个connector,connector的作用是转发请求,此时connector会把acceptor缓存起来。

假设connector收到回复后。connector会通过acceptor向client返回一些数据后,线程2此时须要把acceptor在add进epoll
fd中。

曾经我以为epoll fd是多线程安全的,我就直接通过epoll_ctl(epoll fd。acceptor,add)把acceptor放进epoll fd中。

如今再回首看看,自己是想当然的这样操作了,没有不论什么根据。

孟子曰,“行有不得。反求诸己”。

既然自己无法解开困惑,那就求助伟大的man了。

通过“man epoll_wait”后,得到这么一句话:

NOTES
While one thread is blocked in a call to epoll_pwait(), it is possible for another thread to add a file descriptor to the waited-upon epoll instance. If the new file descriptor becomes ready, it will cause the epoll_wait() call to unblock.
For a discussion of what may happen if a file descriptor in an epoll instance being monitored by epoll_wait() is closed in another thread, see select(2).

翻译后就是:假设一个线程正堵塞在epoll_pwait上。此时可能有另外一个线程要把一个socket fd加入到这个epoll fd上。假设这个这个新的socket fd被加入进去后处于ready状态,那么epoll_wait就不会再处于堵塞状态。假设由epoll fd监控的一个socket fd被另外一个线程close掉。此时系统处于何种状态请參考select(2)。通过"man 2 select"后,得到例如以下一段话:

   Multithreaded applications
If a file descriptor being monitored by select() is closed in another thread, the result is unspecified. On some UNIX systems, select() unblocks and returns, with an indication that the file descriptor is ready (a subsequent I/O operation will likely fail with an error, unless another the file descriptor reopened between the time select() returned and the I/O operations was performed). On Linux (and some other systems), closing the file descriptor in another thread has no effect on select(). In summary, any application that relies on a particular behavior in this scenario must be considered buggy.

翻译后,其意义为:假设一个线程中由select管理的socket被另外一个线程close掉,将会发生什么仅仅有天晓得。

在一些UNIX系统中,select会结束堵塞态并返回,它会标识这个socket处于ready状态(后面对这个socket的操作会失败,os也会给出错误提示,除非在select返回和进程对这个socket进行读写这段时间段内。os又把同一个socket fd分配出去了)。在linux(和其它同类的系统)上,这样的行为不会影响select(即有堵塞态变为非堵塞态)。总之,假设一个程序中这样的行为应该被觉得是一个bug(就不应有这样的行为操作)。

通过以上两段man大神的神示。除了一个线程在epoll或者select中监控一个socket时候另外一个线程对这个socket进行close这样的情况。我就能够觉得多个线程操作同一个epoll fd的行为是安全的。即我上面的操作是没有问题的。

以上是个人愚见。恳请大家批评指正。

另外严厉谴责诸如推酷“www.tuicool.com”这样的垃圾抄袭站点不经本人同意就转载本人blog的行为。

多个线程怎样操作同一个epoll fd的更多相关文章

  1. 如何与多个线程的操作epoll fd

    自己曾经做一个接口server时候,这样的场景下我的设计是多个线程操作同一个epoll fd.彼时,我的理由是epoll的系列函数是线程安全的. 当然有人不理解为什么会有多个线程操作同一个epoll ...

  2. Java多线程操作同一个对象,线程不安全

    Java多线程操作同一个对象 发现问题:多个线程操作同一资源的情况下,线程不安全,数据紊乱 代码: package multithreading; // Java多线程操作同一个对象 // 买火车票的 ...

  3. JDBCToolsV2:利用ThreadLocal保证当前线程操作同一个数据库连接对象。

    JDBCToolsV2:     利用ThreadLocal保证当前线程操作同一个数据库连接对象. package com.dgd.test; import com.alibaba.druid.poo ...

  4. Python多进程操作同一个文件,文件锁问题

    最近工作当中做了一个项目,这个项目主要是操作文件的. 在操作耗时操作的时候,我们一般采用多线程或者多进程.在开发中,如果多个线程需要对文件进行读写操作,就需要用到线程锁或者是文件锁. 使用fcntl ...

  5. 在C#中子线程如何操作主线程中窗体上控件

    在C#中,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能 简单的通过控件对象名来操作,但不是说不能进行操作,微软 ...

  6. 多线程(二)Object类方法、线程的操作sleep(),join(),interrupt(),yield()

    四.Object类简介 Object类是所有类的超类,之所以放在线程部分是因为其方法很多是和线程有关的.比如以下三个: wait()方法.wait(long timeout)和wait(long ti ...

  7. 编写Java程序,实现多线程操作同一个实例变量的操作会引发多线程并发的安全问题。

    查看本章节 查看作业目录 需求说明: 多线程操作同一个实例变量的操作会引发多线程并发的安全问题.现有 3 个线程代表 3 只猴子,对类中的一个整型变量 count(代表花的总数,共 20 朵花)进行操 ...

  8. IPC机制与线程的操作

    目录 Queue模块 IPC机制(进程间通信) 生产者消费者模型 线程理论 创建线程的两种方式 线程实现TCP服务端的并发 线程join方法 线程数据共享 线程对象属性和方法 守护线程 GIL全局解释 ...

  9. Android 子线程 UI 操作真的不可以?

    作者:vivo 互联网大前端团队- Zhang Xichen 一.背景及问题 某 SDK 有 PopupWindow 弹窗及动效,由于业务场景要求,对于 App 而言,SDK 的弹窗弹出时机具有随机性 ...

随机推荐

  1. linux网络相关命令使用

    A,iptables使用示例 1,将请求80端口的包发送给本机8180端口(这样,别的机器访问本机的80端口时会被转发到8180端口去) iptables -t nat -A PREROUTING - ...

  2. java--折半查找

    /* 折半查找 */ class TwoSearch { //折半查找可以提高效率,但必须得保证是有序的数组 public static int halfSearch(int[] arr,int ke ...

  3. ASP.NET页面传值的几种方式

    页面传值是学习asp.net初期都会面临的一个问题,总的来说有页面传值. 存储对象传值.ajax.类.model.表单等!下面欧柏泰克和大家一起来看看asp.net页面传值方式一般有哪些?常用的较简单 ...

  4. jquery 上下滑动效果

    <script type="text/javascript"> var myar = setInterval('AutoScroll(".li_gundong ...

  5. java中只能有一个实例的类的创建

    Java中,如果我们创建一个类,想让这个类只有一个对象,那么我们可以 1:把该类的构造方法设计为private 2:在该类中定义一个static方法,在该方法中创建对象 package test; / ...

  6. BZOJ 1261: [SCOI2006]zh_tree( 区间dp )

    dp(l, r)表示[l, r]这段作为一棵树的最小访问代价. 对于dp(l, r), 我们枚举它的根x, 则dp(l, r) = min(dp(l, x-1)+dp(x+1, r)+C*fx) + ...

  7. BZOJ 3907: 网格( 组合数 + 高精度 )

    (0,0)->(n,m)方案数为C(n,n+m), 然后减去不合法的方案. 作(n,m)关于y=x+1的对称点(m-1,n+1), 则(0,0)->(m-1,n+1)的任意一条路径都对应( ...

  8. mysql里的sql函数

    仅作为自己忘记时的查询 时间 now() 返回当前年-月-日 时:分:秒格式的时间 UNIX_TIMESTAMP() 当前的uninx时间戳 date_format(date,格式) date是年月日 ...

  9. 使用python操作RabbitMQ,Redis,Memcache,SQLAlchemy 其二

    一.概念 1.Memcached     Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态 ...

  10. wchar_t是内置还是别名(亲测有效:wchar_t在windows下是16位整数的别名,在linux等平台下是32位整数的别名。MSVC2008开始默认是/Zc:wchar_t)

    接前一篇C++ ABI之名字改编(以Qt为例),继续看看C++名字改编相关的问题. 问题 MSVC 有一对选项/Zc:wchar_t- 与 /Zc:wchar_t控制wchar_t 于是 wchar_ ...