本身之前作一个接口服务器时候,这种场景下个人设计是多个线程操做同一个epoll fd。彼时,个人理由是epoll的系列函数是线程安全的。 linux
固然有人不理解为何会有多个线程操做同一个epoll fd的情形,这里稍微铺陈一下接口服务器的场景。epoll fd有线程1维护,监听服务端端口的socket的accept出来的acceptor(即新的socket fd)也放在这个epoll fd中。当收到客户端连接请求时候,线程2从链接池connector pool中挑选出来一个connector,connector的做用是转发请求,此时connector会把acceptor缓存起来。若是connector收到回复后,connector会经过acceptor向客户端返回一些数据后,线程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(就不该有这种行为操做)。 app
经过以上两段man大神的神示,除了一个线程在epoll或者select中监控一个socket时候另一个线程对这个socket进行close这种状况,我就能够认为多个线程操做同一个epoll fd的行为是安全的,即我上面的操做是没有问题的。 less
以上是我的愚见,恳请你们批评指正。 socket
另外严厉谴责诸如推酷“www.tuicool.com”这种垃圾抄袭网站不经本人容许就转载本人blog的行为。 ide