select,poll,epoll總結

還在持續學習中,本文是一個階段性的總結。html

1、select

select的核心是不停的遍歷文件描述符,看看是否就緒。通常最多同時支持1024個文件描述符。函數

1.1 select函數

int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
  1. nfds:最大的文件描述符加1
  2. readfds:監聽可讀集合
  3. writefds:監聽可寫集合
  4. exceptfds:監聽異常集合
  5. timeout:超時時間

1.2 select流程

喚醒 當前進程的過程一般是在所監測文件的設備驅動內實現的,驅動程序維護了針對自身資源讀寫的等待隊列。當設備驅動發現自身資源變爲可讀寫而且有進程睡眠在該資源的等待隊列上時,就會喚醒這個資源等待隊列上的進程。性能

1.3 select問題

  1. 每次調用時要重複地從用戶態讀入參數。
  2. 每次調用時要重複地掃描文件描述符,遍歷全部文件描述符。
  3. 每次在調用開始時,要把當前進程放入各個文件描述符的等待隊列。在調用結束後,又把進程從各個等待隊列中刪除
  4. 對文件描述符的數量有限制(通常爲1024個)

select隨着文件描述符數量的上升,性能會急劇降低學習

2、poll

poll的總體流程和select差很少,也是每次遍歷全部文件描述符,性能很差,不過poll解決了select文件描述符數量的限制問題。ui

3、epoll

select和poll運行效率的兩個瓶頸已經找出,如今的問題是怎麼改進。.net

  1. 首先,若是要監聽1000個fd,每次poll都要把1000個fd 拷入內核,這是極大的浪費,內核幹嗎不本身保存已經拷入的fd呢?**epoll就是本身保存拷入的fd **,它的API就已經說明了這一點,不是 epoll_wait的時候才傳入fd,而是經過epoll_ctl把全部fd傳入內核再一塊兒"wait",這就省掉了沒必要要的重複拷貝。
  2. 其次,在 epoll_wait時,也不是把current輪流的加入fd對應的設備等待隊列,而是在設備等待隊列醒來時調用一個回調函數(固然,這就須要「喚醒回調」機制),把產生事件的fd納入一個鏈表,而後返回這個鏈表上的fd。
  3. 另外,epoll機制實現了本身特有的文件系統eventpoll filesystem

3.1 epoll 函數

epoll總共提供了三個函數unix

  1. int epoll_create(int size);

epoll_create是爲了建立一個epoll文件描述符,新建立的epoll文件描述符帶有一個struct eventpoll結構,eventpoll結構以下。code

struct eventpoll {  
    spinlock_t lock;  
    struct mutex mtx;  
    wait_queue_head_t wq;  /* Wait queue used by sys_epoll_wait() ,調用epoll_wait()時, 咱們就是"睡"在了這個等待隊列上*/
    wait_queue_head_t poll_wait;  /* Wait queue used by file->poll() , 這個用於epollfd本事被poll的時候*/
    struct list_head rdllist; /* List of ready file descriptors, 全部已經ready的epitem都在這個鏈表裏面*/ 
    struct rb_root rbr; /* RB tree root used to store monitored fd structs, 全部要監聽的epitem都在這裏*/ 
    epitem *ovflist;  /*存放的epitem都是咱們在傳遞數據給用戶空間時監聽到了事件*/.
    struct user_struct *user; /*這裏保存了一些用戶變量,好比fd監聽數量的最大值等*/  
};

這個結構上再掛一個紅黑樹,而這個紅黑樹就是每次epoll_ctl時fd存放的地方。htm

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

此函數是添加、刪除、修改事件blog

  1. int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

此函數是等待條件知足,返回值爲準備就緒的事件數

3.2 epoll 流程


參考
1.http://www.javashuo.com/article/p-txmndpyl-cm.html
2.https://blog.csdn.net/weixin_42462202/article/details/95315926
3.https://blog.csdn.net/turkeyzhou/article/details/8609360
4.http://blog.chinaunix.net/uid-20643761-id-1594860.html
5.http://blog.chinaunix.net/uid-28541347-id-4236779.html
6.http://blog.chinaunix.net/uid-28541347-id-4238524.html

相關文章
相關標籤/搜索