select模型的原理、優勢、缺點

I/O多路複用(又被稱爲「事件驅動」),首先要理解的是,操做系統爲你提供了一個功能,當你的某個socket可讀或者可寫的時候,它能夠給你一 個通知。這樣當配合非阻塞的socket使用時,只有當系統通知我哪一個描述符可讀了,我纔去執行read操做,能夠保證每次read都能讀到有效數據而不 作純返回-1和EAGAIN的無用功。寫操做相似。操做系統的這個功能經過select/poll/epoll之類的系統調用來實現,這些函數均可以同時 監視多個描述符的讀寫就緒情況,這樣,**多個描述符的I/O操做都能在一個線程內併發交替地順序完成,這就叫I/O多路複用,這裏的「複用」指的是複用 同一個線程。編程

I/O複用之select

一、介紹: 
select系統調用的目的是:在一段指定時間內,監聽用戶感興趣的文件描述符上的可讀、可寫和異常事件。poll和select應該被歸類爲這樣的系統 調用,它們能夠阻塞地同時探測一組支持非阻塞的IO設備,直至某一個設備觸發了事件或者超過了指定的等待時間——也就是說它們的職責不是作IO,而是幫助 調用者尋找當前就緒的設備。 
下面是select的原理圖:數組

   

2 、select系統調用API以下:網絡

 
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
 

fd_set結構體是文件描述符集,該結構體其實是一個整型數組,數組中的每一個元素的每一位標記一個文件描述符。fd_set能容納的文件描述符 數量由FD_SETSIZE指定,通常狀況下,FD_SETSIZE等  於1024,這就限制了select能同時處理的文件描述符的總量。併發

三、下面介紹一下各個參數的含義: 
    1)nfds參數指定被監聽的文件描述符的總數。一般被設置爲select監聽的全部文件描述符中最大值加1; 
    2)readfds、writefds、exceptfds分別指向可讀、可寫和異常等事件對應的文件描述符集合。這三個參數都是傳入傳出型參數,指的是 在調用select以前,用戶把關心的可讀、可寫、或異常的文件描述   符 經過FD_SET(下面介紹)函數分別添加進readfds、writefds、 exceptfds文件描述符集,select將對這些文件描述符集中的文件描述符進行監聽,若是有就緒文件描述符,select會重置readfds、writefds、exceptfds文件描述符集來通知應用程序哪些文件描述符就緒。這個特性將致使select函數返回後,再次調用select以前,必須重置咱們關心的文件描述符,也就是三個文件描述符集已經不是咱們以前傳入 的了。 
   3)timeout參數用來指定select函數的超時時間(下面講select返回值時還會談及)。socket

 
struct timeval
{
    long tv_sec;        //秒數
    long tv_usec;       //微秒數
};
 

四、下面幾個函數(宏實現)用來操縱文件描述符集:函數

 
void FD_SET(int fd, fd_set *set);   //在set中設置文件描述符fd
void FD_CLR(int fd, fd_set *set);   //清除set中的fd位
int  FD_ISSET(int fd, fd_set *set); //判斷set中是否設置了文件描述符fd
void FD_ZERO(fd_set *set);          //清空set中的全部位(在使用文件描述符集前,應該先清空一下)
    //(注意FD_CLR和FD_ZERO的區別,一個是清除某一位,一個是清除全部位)
 

五、select的返回狀況: 
1)若是指定timeout爲NULL,select會永遠等待下去,直到有一個文件描述符就緒,select返回; 
2)若是timeout的指定時間爲0,select根本不等待,當即返回; 
3)若是指定一段固定時間,則在這一段時間內,若是有指定的文件描述符就緒,select函數返回,若是超過指定時間,select一樣返回。 
4)返回值狀況: 
a)超時時間內,若是文件描述符就緒,select返回就緒的文件描述符總數(包括可讀、可寫和異常),若是沒有文件描述符就緒,select返回0; 
b)select調用失敗時,返回 -1並設置errno,若是收到信號,select返回 -1並設置errno爲EINTR。spa

六、文件描述符的就緒條件: 
在網絡編程中, 
1)下列狀況下socket可讀: 
a) socket內核接收緩衝區的字節數大於或等於其低水位標記SO_RCVLOWAT; 
b) socket通訊的對方關閉鏈接,此時該socket可讀,可是一旦讀該socket,會當即返回0(能夠用這個方法判斷client端是否斷開鏈接); 
c) 監聽socket上有新的鏈接請求; 
d) socket上有未處理的錯誤。 
2)下列狀況下socket可寫: 
a) socket內核發送緩衝區的可用字節數大於或等於其低水位標記SO_SNDLOWAT; 
b) socket的讀端關閉,此時該socket可寫,一旦對該socket進行操做,該進程會收到SIGPIPE信號; 
c) socket使用connect鏈接成功以後; 
d) socket上有未處理的錯誤。操作系統

select優勢:線程

   select模型是Windows sockets中最多見的IO模型。它利用select函數實現IO 管理。經過對select函數的調用,應用程序能夠判斷套接字是否存在數據、可否向該套接字寫入據。3d

    如:在調用recv函數以前,先調用select函數,若是系統沒有可讀數據那麼select函數就會阻塞在這裏。當系統存在可讀或可寫數據時,select函數返回,就能夠調用recv函數接   收數據了。

   能夠看出使用select模型,須要兩次調用函數。第一次調用select函數第二次socket API。使用該模式的好處是:能夠等待多個套接字。

select缺點: (1)每次調⽤用select,都須要把fd集合從⽤用戶態拷貝到內核態,這個開銷在fd不少時會很⼤大 (2)同時每次調⽤用select都須要在內核遍歷傳遞進來的全部fd,這個開銷在fd不少時也很⼤大 (3)select⽀支持的⽂文件描述符數量太⼩小了,默認是1024

相關文章
相關標籤/搜索