IO多路復用模型之Select

2021-08-11 05:56:25 字數 2724 閱讀 4445

在unix/c中,socket相關的函式操作都是阻塞式的,在單執行緒下服務端只能處理乙個客戶端請求。採用多執行緒處理客戶端請求,雖然能充分發揮多核cpu能力,但是在客戶端連線過多,併發度維持相對較高水平時,多執行緒引起執行緒的上下文切換將導致系統效率低下。select多路復用模型的核心思想,在單執行緒下處理多客戶端連線,unix/c提供了相應函式庫,具體如下:

int select (int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,

const struct timeval* timeout);

struct timeval ;

fd_set是乙個socket鍊錶,以下巨集可以對該佇列進行操作:

fd_clr( s, *set) 從佇列set刪除控制代碼s;

fd_isset( s, *set) 檢查控制代碼s是否存在與佇列set中;

fd_set( s, *set )把控制代碼s新增到佇列set中;

fd_zero( *set ) 把set佇列初始化成空佇列.

select執行流程:

1:用fd_zero巨集來初始化我們感興趣的fd_set。

2:用fd_set巨集來將套接字控制代碼分配給相應的fd_set。

3:呼叫select函式

4:用fd_isset對套接字控制代碼進行檢查。

服務端**如下:

#include 

#include

#include

#include

#include

#include

#include

#include

#define port 8080

#define backlog 1024

#define bufsize 64

int client_count;

int main()

int select_ret = -1;

if((select_ret = select(max_fd+1, &socket_fd, null, null, &tik)) < 0)

if(select_ret == 0)

continue;

for(index = 0;index < client_count;index++)

if(fd_isset(fds[index], &socket_fd))

read_handler(&fds[index]);//處理io事件

if(fd_isset(server_socket, &socket_fd))

connect_handler(server_socket, fds + client_count);//處理連線

}return0;}

char *get_client_info(int client_fd)

void read_handler(int *socket_fd)else

if(len == 0 )else

}void connect_handler(int server_socket, int *fd)else

}int create_socket(struct sockaddr_in socket_addr, int backlog)

int on = 1;

setsockopt(server_socket, sol_socket, so_reuseaddr, &on, sizeof(on));

int bind_ret = -1;

if((bind_ret = bind(server_socket, &socket_addr, sizeof(socket_addr)))<0)

int listen_ret = -1;

if((listen_ret = listen(server_socket, backlog))<0)

return server_socket;

}

客戶端**:

#include 

#include

#include

#include

#include

#define port 8080

int main()

connect(socket_fd, &client_addr, sizeof(client_addr));

char send_buf[64],recv_buf[64];

memset(send_buf, 0, sizeof(send_buf));

memset(recv_buf, 0, sizeof(recv_buf));

while(fgets(send_buf,sizeof(send_buf),stdin)!=null)

close(socket_fd);

return

0;}

執行效果如下圖:

小結:select模型解決了單執行緒下,無法處理多客戶端請求問題。但由於其採用輪詢策略依次去處理所有socket控制代碼,而通常大多數連線處理不活躍狀態,這導致輪詢效率低下;實驗表明,在大部分客戶端不活躍而維持長連線狀態時,select多路復用模型的效率並不比多執行緒分別處理客戶端效率高。此外,由於select基於檔案描述符實現多路復用,其最大併發處理的併發數也受到作業系統相應的限制(linux預設1024)。

多路復用IO模型之select

多路i o復用表示支援多個任務同時對某一程序的i o程序操作,普通的read write只能實現同一時間操作乙個,無法實現網路通訊的併發操作。那麼多路復用i o分為三種機制 select poll epoll 1.占用記憶體多 2.程序 執行緒 切換時間多。3.程序 執行緒 之間同步麻煩 在主控執行...

IO多路復用 select模型

客戶端 見 c s通訊 伺服器阻塞型使用 伺服器端 include include include include include include include include include include include include int main set local address m...

IO多路復用 select

select系統呼叫的目的是 在一段指定時間內,監聽使用者感興趣的檔案描述符上的可讀 可寫和異常事件。poll和select應該被歸類為這樣的系統 呼叫,它們可以阻塞地同時探測一組支援非阻塞的io裝置,直至某乙個裝置觸發了事件或者超過了指定的等待時間 也就是說它們的職責不是做io,而是幫助 呼叫者尋...