Linux IO同步復用

2021-10-10 01:14:44 字數 3358 閱讀 4509

關於同步與非同步:

同步:呼叫者在執行乙個呼叫時,一直等待呼叫完成返回後才進行後續操作。

非同步:呼叫者執行乙個呼叫時,立即返回,繼續進行後續操作而不關心呼叫是否完成。

非同步與同步是對通訊機制的描述,而阻塞、非阻塞關心的是呼叫者的狀態

阻塞:當執行乙個呼叫時,呼叫者執行緒一直被掛起(cpu時間片切換給其它執行緒),直到呼叫完成返回。

非阻塞:當執行乙個呼叫時,呼叫者執行緒仍然活躍。

值得注意的是同步呼叫過程,在等待過程執行緒可能並沒有掛起,而只是一直等待(占用著資源)。

io多路復用:是一種同步io模型,通過乙個執行緒來監視一組檔案描述符,每當乙個檔案控制代碼就緒時,就通知應用程式進行io讀寫操作。多路指代多個網路連線,復用指在乙個執行緒執行。其本質是時分復用

最早的io阻塞模型,其通過乙個執行緒來處理乙個連線,當執行recv等函式是,執行緒將一直掛起等待,直到函式返回,這樣的模型效率低下(一次只能處理乙個連線,並且一直等待呼叫返回)。

可以知道,io多路復用本質是採取乙個執行緒來監視一組 sock(io流)狀態,即多路網路連線復用乙個io執行緒,以達到對多個io流的管理,藉此提高伺服器的吞吐能力和處理多連線的效能。

linux下的網路io模型,普通模型和復用模型區別為:

即:原本需要多執行緒/多程序來處理的多個socket 的任務改為 採取乙個執行緒輪詢處理

linux中實現io復用的方式包含三大類:select poll  epoll

linux io復用方式

select

poll

epoll

資料結構

bitmap

陣列紅黑樹

最大鏈結數

1024

無上限無上限

查詢效率

o(n) 輪詢

o(n) 輪詢

o(1)

io復用模型類似於汽車過橋:

多輛汽車表明多個網路連線,共用一座橋,在乙個執行緒中進行io操作。

select:依次詢問橋一側的汽車誰需要過橋(檔案描述符就緒),返回就緒的汽車。

poll:依次詢問橋一側的汽車誰需要過橋,但相比較與select 沒有汽車總量的上限。

epoll:不需要詢問,當汽車就緒需要過橋時,發出乙個訊號表明自己就緒。

select:

linux中select採取bitmap的資料結構實現,其將待監視的檔案描述符,在fd對應的bit位設定為1,其它不需要監視的位置設為0.將這張檔案描述符監視表拷貝入核心空間kernel space 核心進行輪詢,將那些io未就緒的檔案位置設為0,就緒位置仍然保留1,select函式返回後,使用者執行緒即可獲取到那些就緒的檔案,進行相應的io操作。

select檔案監視表結構:

建立監視檔案描述符表

將需要監聽的檔案在表中對應位置設定為1(呼叫fd_set函式)

呼叫select函式,切換到核心態,查詢相應檔案狀態。

select函式返回後,遍歷那些就緒的檔案,執行io操作

重複234,以實現在乙個執行緒中不斷輪訓處理。

首先實現乙個客戶端程式:

將連線上本機的埠12000  並不斷的傳送 / 接受訊息

#include#include#include#include #include #include#include#include #define sport 12000

#define size 128

#define addr "127.0.0.1"

using namespace std;

int main()

send(sock_fd,str.c_str(),str.size(),0);

//向sock_fd檔案寫入資料

if(0接下來實現伺服器的io多路復用程式:基於select

create_server函式實現建立乙個伺服器監聽的埠,成功返回乙個sock fd檔案描述符

int create_server(const char* ip,int port)

; struct sockaddr_in addr;

if(fd_isset(fd,readfds)) //這裡每次進來都檢視 監聽fd是否有新連線訊息

{cout<

if(0>newfd)

{cout<

先初始化readfds tempfds 即監視的檔案描述符表  結構為 fd_set

建立監聽埠,生成sock_fd  同時開始輪訓while(1) 的執行系統呼叫select  查詢是否有就緒事件:

int main()

{ int ret=0;

int sock_fd=0;

int maxfd=0;

fd_set readfds;// 會拷貝到kernel space 核心空間作更改

fd_set tempfds;//user space 使用者空間的fd_set

sock_fd=create_server(addr,sport);//建立伺服器 fd

if(0>sock_fd)

{cout<

{cout

通過g++ 編譯生成兩個可執行檔案 client 和 server_select

./sever_select 啟動伺服器 同時執行 ./client 啟動多個客戶端

執行結果如下:

由此可見:

select方式基於對乙個fd_set 監視檔案表的修改,應用程式可以採取遍歷的方式,將那些就緒的檔案(對應bit為1)進行io操作。

那麼可以實現在乙個執行緒中處理多個socket連線,即:多個網路連線(sock_fd)使用乙個io執行緒

Linux IO同步復用

io復用通過時分復用的形式,多個socket連線使用同乙個io執行緒,io執行緒通過系統呼叫的方式獲知被監視的檔案識別符號列表中就緒的檔案,執行io操作。這裡的同步指代在執行io操作時,會等待動作完成再繼續執行,復用是採取乙個執行緒完成對多個io流的處理。linux中poll方式是對select的改...

Linux IO多路復用

一.select 函式 include include include int select int n,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout fd clr int fd,fd set set f...

Linux I O復用技術 poll

1.介紹 poll函式的作用是檢測一組 socket 中某個或某幾個是否有 事件 就緒,即可讀 可寫。在linux平台下的poll定義如下 include int poll struct pollfd fds,nfds t nfds,int timeout 引數 struct pollfd 對於st...