關於什麼是I/O多路複用,在知乎上有個很好的回答,能夠參考羅志宇前輩的回答
記錄下本身的理解:忘記這個坑爹的中文翻譯。記住I/O multiplexing
linux
I/O multiplexing 這裏面的 multiplexing 指的實際上是在單個線程經過記錄跟蹤每個Sock(I/O流)的狀態來同時管理多個I/O流.
I/O多路複用這一技術。簡單來講,就是一個線程追蹤多條io流(讀,寫,異常),但不使用輪詢,而是由設備自己告知程序哪條流可用了,這樣一來就解放了cpu,也充分利用io資源,下文主要講解如何實現這一技術,linux下這一技術有三個實現,select,poll,epoll。數組
阻塞I/O模式下,內核對於I/O事件的處理是阻塞或者喚醒,而非阻塞模式下,咱們能夠經過循環把集合中的流從頭至尾問一遍,這樣就能夠處理多個流了,但這樣的作法顯然很差,由於若是全部流都沒有數據,那麼只會白白浪費CPU.
爲了不CPU空轉,能夠引進了一個代理(一開始有一位叫作select的代理,後來又有一位叫作poll的代理,不過二者的本質是同樣的)。這個代理比較厲害,能夠同時觀察許多流的I/O事件,在空閒的時候,會把當前線程阻塞掉,當有一個或多個流有I/O事件時,就從阻塞態中醒來,因而咱們的程序就會輪詢一遍全部的流安全
此種方法與select類似,不做介紹函數
#include <sys/select.h> /** *select將更新這個集合,把其中不可讀的套節字去掉只保留符合條件的套節字在這個集合裏面 */ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
參數readfds、writefds、exceptfds都是指向文件描述符的指針,數據類型爲fd_set。而readfds是用來檢測輸入的,writefds是用來檢測輸出的,exceptfds使用檢測是否異常的。有關fd_set一般有四個宏供咱們操做:FD_ZERO、FD_SET、FD_CLR、FD_ISSET。spa
文件描述符集合有一個最大容量限制,由常量FD_SETSIZE來決定,在Linux上,該常量值爲1024。
參數timeout爲超時時間。線程
#include <stdio.h> #include <unistd.h> #include <sys/select.h> int main(void) { int bytes_read, ready; char buffer[128]; fd_set readfds; struct timeval timeout; FD_ZERO(&readfds); FD_SET(STDIN_FILENO, &readfds); timeout.tv_sec = 10; timeout.tv_usec = 0; ready = select(STDIN_FILENO+1, &readfds, NULL, NULL, &timeout); if (ready) { bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer)); if (buffer[bytes_read - 1] == '\n') buffer[bytes_read - 1] = '\0'; printf("%s\n", buffer); } else { printf("No data to read\n"); } return 0; }
因爲I/O Multiplexing->select存在如下問題翻譯
所以14年後(1997)出現了POLL,修復select的如下問題設計
#include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout); struct pollfd{ int fd; //文件描述符 short events; //等待的事件 short revents; //實際發生的事件 };
每一個pollfd結構體指定了一個被監視的文件描述符。第一個參數是一個數組,即poll函數能夠監視多個文件描述符。每一個結構體的events是監視該文件描述符的事件掩碼,由用戶來設置。revents是文件描述符的操做結果事件,內核在調用返回時設置。events中請求的任何事件均可能在revents中返回
3d
問題:使用select,咱們有O(n)的無差異輪詢複雜度,隨着處理的流越多,無差異輪詢時間就越長
此時epoll產生,epoll能夠理解爲event poll,不一樣於(select/poll)無差異輪詢,epoll之會把哪一個流發生了怎樣的I/O事件通知咱們。此時咱們對這些流的操做都是有意義的。代理