自己曾经做一个接口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. JDFS:一款分布式文件管理实用程序第一篇(线程池、epoll、上传、下载)

    一 前言 截止目前,笔者在博客园上面已经发表了3篇关于网络下载的文章,这三篇博客实现了基于socket的http多线程远程断点下载实用程序.笔者打算在此基础上开发出一款分布式文件管理实用程序,截止目前 ...

  3. [WinForm]WinForm跨线程UI操作常用控件类大全

    前言 在C#开发的WinForm窗体程序开发的时候,经常会使用多线程处理一些比较耗时之类的操作.不过会有一个问题:就是涉及到跨线程操作UI元素. 相信才开始接触的人一定会遇上这个问题. 为了解决这个问 ...

  4. c#线程间操作UI-Invoke和BeginInvoke

    利用Invoke和或BeginInvoke实现线程间操作UI的简单例子. /* 窗体包含一个button和一个richtextbox控件 * 注:必须在子线程中执行Invoke和或BeginInvok ...

  5. Winform软件,不要在线程里操作UI

    对于Winform软件,不要在线程里操作UI,不要相信:StartForm.CheckForIllegalCrossThreadCalls = false; 于是,把所有的代码都改成主线程委托调用的方 ...

  6. 【问题解决】线程间操作无效:从不是创建控件“textBox1”的线程访问它

    背景 通过一个辅助线程计算出的一个值赋给textBox1.text: 解决办法 1.直接在窗体的构造函数中添加: System.Windows.Forms.Control.CheckForIllega ...

  7. 关于“线程间操作无效: 从不是创建控件’textBox1‘的线程访问它”异常的解决方法

    线程间操作无效: 从不是创建控件“textBox1”的线程访问它 背景:通过一个辅助线程计算出的一个值赋给textBox1.text;解决办法:1.直接在窗体的构造函数中加:System.Window ...

  8. 为什么在非UI线程中操作UI的改变失不安全的

    因为你如果允许在非UI线程更新操作UI的东西,那我再另一个非UI线程也可以更新这个Ui的东西 这样就会有冲突,比如你的线程刚好跑到修改UI这里,我的另一个UI也有可能跑到这里,所以这样导致线程不安全. ...

  9. bug:C#线程间操作无效: 从不是创建控件" XX" 的线程访问它

    今天遇到这个问题,百度了下,把解决的方法总结出来.我们在ui线程创建的子线程操作ui控件时,系统提示错误详细信息为:线程间操作无效: 从不是创建控件“XXX”的线程访问它. 就我知道的有三种方法,先看 ...

随机推荐

  1. android画笔错位问题的解决

    下面的画画板的代码: public class MainActivity extends Activity { private ImageView iv; private Bitmap baseBit ...

  2. 高效合并两个有序数组(Merge Sorted Array)

    Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: Y ...

  3. python+ueditor+七牛云存储整合

    开发环境:python pyramid. 參考网址:http://developer.qiniu.com/docs/v6/sdk/python-sdk.html,http://my.oschina.n ...

  4. Android中倒计时代码

    布局: maina.xml <DigitalClock android:id="@+id/myClock" android:layout_width="wrap_c ...

  5. hdu1267(递推)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1267 题意:假定一个字符串由m个H和n个D组成,从左到右扫描该串,如果字符H的累计数总是不小于字符D的 ...

  6. DB2错误代码

    db2错误代码大全 博客分类: 数据库 sqlcode sqlstate 说明 000 00000 SQL语句成功完毕 01xxx SQL语句成功完毕,可是有警告 +012 01545 未限定的列名被 ...

  7. MapReduce 异常 LongWritable cannot be cast to Text

    有一个txt文件,内容格公式是这样的: 深圳订做T恤 5729944 深圳厂家t恤批发 5729945 深圳定做文化衫 5729944 文化衫厂家 5729944 订做文化衫 5729944 深圳t恤 ...

  8. 解压system.img

    解压: All-Series:~$ simg2img system.img system.img.ext4 All-Series:~$ mkdir tmp All-Series:~$ mount -t ...

  9. DataInputStream类readLong()引起的思考

    今天无意中看了下jdk中的DataInputStream类,然后看到readLong()方法,如下: private byte readBuffer[] = new byte[8]; public f ...

  10. vb.net WPF webbrowser window.close 关闭后不触发 WindowClosing 事件 WNDPROC解决方式

     vb.net WPF webbrowser window.close 关闭后不触发 WindowClosing 事件 WNDPROC解决方式 #Region "WPF 当浏览器窗体关闭 ...