天天看點

Linux-I/O多路複用原理(select,poll,epoll)Linux-I/O多路複用(select,poll,epoll)

Linux-I/O多路複用(select,poll,epoll)

文章目錄

  • Linux-I/O多路複用(select,poll,epoll)
    • select
      • 函數原型
      • 缺點
    • poll
      • 函數原型
      • 對select改進
    • epoll
      • 函數原型
      • 改進
      • 觸發模式
      • 應用

select

函數原型

select系統調用會阻塞程序,當有資料到來系統将fd_set對應位置位,select函數傳回.select會将fd_set拷貝到核心.其實select隻能傳回一個準備好的檔案描述符,如果在主線程對相應的檔案描述符做操就會阻塞,使得其他準備好的檔案描述符得不到處理,是以就有了Reactor模型.

#include <sys/select.h>
 
int select(int nfds, fd_set *rdfds, fd_set *wtfds,
                fd_set *exfds, struct timeval *timeout)
           

缺點

  • fd_set組成的bitmap隻有1024個
  • fd_set不可重用,每次都要重新設定fd_set
  • 拷貝fd_set有開銷
  • 需要周遊fd_set

poll

函數原型

poll使用了pollfd結構體,有資料到來系統将polfd.revents置位

對select改進

  • 使用pollfd數組,可以管理大于1024個檔案描述符
  • pollfd可重用
  • 周遊範圍變小(pollfd數組),poll傳回準備好的檔案描述符個數

epoll

函數原型

有資料到來系統将epfd用重排來置位(将有資料的epfd放在數組前面)

//建立size個監聽,傳回一個紅黑樹的檔案描述符epfd
int epoll_create(int size)
//epfd控制
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
//等待epfd準備好
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
           

使用以下指令檢視可以使用的pollfd數量

cat /proc/sys/fs//file-max
           

改進

  • epfd使用者态與核心态共用
  • 周遊範圍變小(準備好的epfd數組),epoll_wait傳回準備好的檔案描述符個數

觸發模式

  • 邊沿觸發(ET):檔案描述符從無資料狀态到有資料狀态epoll才觸發
  • 水準觸發(LT):檔案描述符有資料epoll就觸發

應用

  • redis
  • nginx
  • java NIO(Linux系統)