epoll在多线程下的使用
首先让我们思考一个问题,当一个进程正在阻塞在epoll_wait的时候,另一个线程调用epoll_ctl时会发生什么呢,这个动作安全吗?
测试当epoll_wait期间另一个线程执行epoll_ctl是否安全
其实这种动作是安全的(测试平台为linux,内核为4.4版本),先看一下man里面的描述,可见是安全的。
1.下面让我们来测试一下,首先把fd2加入监听,然后再调用epoll_wait,在wait期间再另一个线程在调用epoll_ctl把fd1加入监听,然后再往fd1里写入数据,可见epoll_wait返回了,证明fd1加入之间没有时间发生时,在wait期间把它加入监听是安全的。代码见下,有点乱,大家凑合着看吧。。。。
可见输出为4,因为文件描述符0,1,2被用掉了,然后先建立的fd2,后建立的fd1,所以fd2为3,fd1为4。
测试epoll_wait时另一个线程关闭了监听的文件描述符
2.下面我们再测试一下在加入之间fd1就可读时epoll_wait会不会丢失这个可读事件,代码稍微改一下就可,见下图。
由上面结果可见,不会丢失可读事件。
3.再考虑下如果在epoll_wait期间,另外一个线程把其中的一个监听文件描述符关闭了会怎么样。先看一段描述
测试代码见下
可见是没有影响的
4.但是让我们再考虑一下,如果关闭了fd1之后又有别的线程打开文件后获得的文件描述符和以前关闭的一样会有什么影响呢。
可见关闭后再写fd1对epoll是没有影响的,即使关闭后又打开时获得的文件描述符一样,看起来效果就像当关闭这个文件描述符时,就把它从监听文件描述符里面给移除了。