epoll 使用詳解--epoll_ctl


添加套接字:

int epoll_ctl(int epfd , int op , int fd , struct epoll_event * event );

 參數詳解:

  epfd:就是指定epoll文件描述符。

  op : 需要執行的操作,添加,修改,刪除,詳細如下。

    EPOLL_CTL_ADD
      在epoll的監視列表中添加一個文件描述符(即參數fd),指定監視的事件類型(參數event)。
    EPOLL_CTL_MOD
      修改監視列表中已經存在的描述符(即參數fd),修改其監視的事件類型(參數event)。
    EPOLL_CTL_DEL
      將某監視列表中已經存在的描述符(即參數fd)刪除,參數event傳NULL。

  fd:需要添加,修改,刪除的套接字。
    event:需要epoll監視的時間類型。
        struct epoll_event定義為:

typedef union epoll_data {
      void *ptr;
       int fd;
      uint32_t u32;
      uint64_t u64;
} epoll_data_t;

struct epoll_event {
      uint32_t events; /* Epoll 監視的事件類型 */
      epoll_data_t data; /* 用戶數據 */
};

  struct epoll_event由兩個成員組成,事件類型和用戶數據。
  data:
  我們先說用戶數據data,從上面代碼可以看到,data是一個聯合體類型,可以是指針,文件描述符,整形(機器字長)。這個數據傳給epoll以后,epoll不會使用,只會在對應的事件觸發后原樣的返回給用戶。實際開發中一般都是保存添加的套接字的描述符,用於當epoll事件返回時識別事件。如果有需要傳其它值也可以,比如改成一個結構體或者對象的地址(可以避免一次使用套接字查找對象操作)。

  events:
  是一個事件集合,通過位掩碼的方式表示不同的事件,可以同時設置多個,通過“|” 連接,可選項如下。
    EPOLLIN
      文件描述符是否可讀。
    EPOLLOUT
      文件描述符是否可寫。
    EPOLLRDHUP(Linux 2.6.17以后才能使用)
      對端關閉連接(被動),或者套接字處於半關閉狀態(主動),這個事件會被觸發。當使用邊緣觸發模式時,很方便寫代碼測試連接的對端是否關閉了連接。
      EPOLLPRI
      文件描述符是否異常
    EPOLLERR
      文件描述符是否錯誤。如果文件描述符已經關閉,繼續寫入也會收到這個事件。這個事件用戶不設置也會被上報。
    EPOLLHUP
      套接字被掛起(所謂的被掛起是指??)。這個事件用戶不設置也會被上報。
     EPOLLET
      設置epoll的觸發模式為邊緣觸發模式。如果沒有設置這個參數,epoll默認情況下是水平觸發模式。詳細可以參考后續的【epoll邊緣觸發與水平觸發】。
      這是一個輸入類型的參數,epoll_wait(2)不會返回這種事件。
    EPOLLONESHOT(Linux 2.6.2以后才支持)
      設置添加的事件只觸發一次,當epoll_wait(2)報告一次事件后,這個文件描述符后續所有的事件都不會再報告。只是禁用,文件描述符還在監視隊列中,用戶可以通過epoll_ctl()的EPOLL_CTL_MOD重新添加事件。
      這是一個輸入類型的參數,epoll_wait(2)不會返回這種事件。
      EPOLLWAKEUP (Linux 3.5以后才支持)
      xxxxx。
      這是一個輸入類型的參數,epoll_wait(2)不會返回這種事件。
       EPOLLEXCLUSIVE (Linux 4.5以后才支持)
      xxxxx
      這是一個輸入類型的參數,epoll_wait(2不會返回這種事件。

返回值:

  成功epoll_ctl()返回0。錯誤返回-1。錯誤碼error會被設置。

錯誤碼:
  EBADF :epfd或者fd不是一個有效的文件描述符。
  EEXIST :當參數是EPOLL_CTL_ADD時,當添加到fd已經在epfd中時,重復添加。
  EINVAL :
    1、當epfd不是一個文件描述符,或者fd是一個epfd,或者op是不支持的參數。
    2、設置了參數EPOLLEXCLUSIVE,卻沒有和其它有效的參數一起設置。
    3、使用參數EPOLL_CTL_MOD 時同時包含了EPOLLEXCLUSIVE
    4、使用參數EPOLL_CTL_MOD 時,當前epfd中的fd之前已經被設置了EPOLLEXCLUSIVE。
    5、EPOLLEXCLUSIVE ??????
  ELOOP :epoll監視隊列是可以添加epoll描述符的,就是支持嵌套。當嵌套關系成環時,或者嵌套深度超過5層時,會報這個錯誤。
  ENOENT :使用EPOLL_CTL_MOD 和EPOLL_CTL_DEL添加 修改時,修改的套接字卻不在epoll的監視隊列中。
  ENOMEM :操作所需要的內存不夠。
  ENOSPC :當EPOLL_CTL_ADD添加時,已經超過了epoll的規格限制。規格限制在:/proc/sys/fs/epoll/max_user_watches。
  EPERM :添加的fd不支持epoll。比如添加的是普通文件描述符。

BUGS:
  1、在Linux內核版本2.6.9之前,EPOLL_CTL_DEL操作時,event必須是一個非空的指針,實際並沒有使用。2.6.9內核版本以后可以直接設置為NULL。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM