1. 程式人生 > 其它 >epoll --水平觸發與邊緣觸發

epoll --水平觸發與邊緣觸發

  epoll 提供了邊沿觸發 (ET) 和電平觸發 (LT)的事件觸發方式。兩種機制的區別如下:

  先假設出現如下情況:

  1. 某個有一個管道已經建立連線,fd加入了epoll中,監測可讀事件。
  2. 管道的寫入者,寫入了2KB的資料。
  3. 讀取者呼叫epoll_wait()成功返回了事件。
  4. 但是管道的讀取者只讀取了1KB 的資料。
  5. 讀取者讀取結束,再次呼叫epoll_wait()

  如果使用者在新增fd到epoll時,使用了引數EPOLLET(邊緣觸發)。 當讀執行緒執行第5步的時候,執行緒可能會被掛起,儘管緩衝區彙總還存在資料,與此同時遠端可能在等待當前執行緒的相應。邊緣觸發就是套接字的狀態改變時才觸發,具體說就是從不可讀到切換到可讀的這一瞬間才會觸發。所以可能會導致第5步被永久的阻塞。

  使用邊緣觸發時,應該避免使用阻塞的套接字,以避免部分的套接字被餓死。具體建議如下:

  1、使用非阻塞的檔案描述符

  2、只有當read或write返回EAGAIN以後,才再次呼叫wait(就是資料全部讀寫完成了)。

 

  水平觸發模式是預設的模式。

  

優點:

  當多個執行緒或程序同時wait同一個epoll時,如果設定了邊緣觸發,可以避免出現“驚群”效應,把所有的執行緒都喚醒了。