epoll的EPOLLIN和EPOLLOU為什么不能同時關聯 http://laokaddk.blog.51cto.com/368606/791945
epoll使用總結 http://laokaddk.blog.51cto.com/368606/617497
epoll學習:思考一種高性能的服務器處理框架 http://laokaddk.blog.51cto.com/368606/607231
epoll學習筆記 http://laokaddk.blog.51cto.com/368606/607017
簡單學習了一下epoll,之前也用過,這次又看了看,收獲如下:
兩種實現模式(在http://laokaddk.blog.51cto.com/368606/791945中都有提到):同一個線程 和 不同線程;
順便了解了一下驚群現象,如果用accept阻塞的方式就不存在驚群現象了,在不同線程中通過epoll_wait來出發accept行為的nginx的解決方法是通過進程里原子的修改寄存器a來做到進程間互斥的。
在不同線程模式下:listenfd需設置為非阻塞,注冊EPOLLIN就可以了,觸發時調用accept,有沒有連接都會立刻返回;
在同一個線程模式下:listenfd為阻塞模式,不注冊epoll,阻塞while調用accept即可;
ET觸發只支持非阻塞模式,這里針對的fd是accept接收到的然后epoll_add了的那些fds,原因是:因為ET觸發需要處理函數一直處理完所有in/out數據,比如read數據,如果read到的字節數小于預先準備讀入的字節數,那么就可以認為讀完了;如果是非阻塞模式,那么read會一直阻塞在那里。
epollfd不需要設置阻塞、非阻塞。
一般都用LT觸發,不論哪種實現模式,EPOLLIN和EPOLLOUT都不同時設定,都是不斷切換來做的。
客戶端close掉socket時,會喚醒服務端epoll_wait;
對于epoll_wait而言,針對一個fd只存在喚醒與被喚醒,至于是EPOLLIN還是EPOLLOUT,取決于你當初epoll_add時的設定,因此如果你epoll_add時設定了EPOLLIN|EPOLLOUT,那么當EPOLLIN發生時(內核里當然是可以區分EPOLLIN和EPOLLOUT的),你收到的fd上的事件依然是EPOLLIN|EPOLLOUT。
http://my.oschina.net/costaxu/blog/127394
http://blog.csdn.net/guomsh/article/details/8484222
http://blog.csdn.net/guomsh/article/details/8478209
http://blog.csdn.net/ctthuangcheng/article/details/8596818
http://blog.yunn.io/archives/114/