I O多路復用

2021-07-25 21:35:22 字數 2309 閱讀 9894

關於i/o多路復用(又被稱為「事件驅動」),首先要理解的是,作業系統為你提供了乙個功能,當你的某個socket可讀或者可寫的時候,它可以給你乙個通知。這樣當配合非阻塞的socket使用時,只有當系統通知我哪個描述符可讀了,我才去執行read操作,可以保證每次read都能讀到有效資料而不做純返回-1和eagain的無用功。寫操作類似。作業系統的這個功能通過select/poll/epoll/kqueue之類的系統呼叫函式來使用,這些函式都可以同時監視多個描述符的讀寫就緒狀況,這樣,多個描述符的i/o操作都能在乙個執行緒內併發交替地順序完成,這就叫i/o多路復用,這裡的「復用」指的是復用同乙個執行緒。

以select和tcp socket為例,所謂可讀事件,具體的說是指以下事件:

1 socket核心接收緩衝區中的可用位元組數大於或等於其低水位so_rcvlowat;

2 socket通訊的對方關閉了連線,這個時候在緩衝區裡有個檔案結束符eof,此時讀操作將返回0;

3 監聽socket的backlog佇列有已經完成三次握手的連線請求,可以呼叫accept;

4 socket上有未處理的錯誤,此時可以用getsockopt來讀取和清除該錯誤。

所謂可寫事件,則是指:

1 socket的核心傳送緩衝區的可用位元組數大於或等於其低水位so_sndlowait;

2 socket的寫端被關閉,繼續寫會收到sigpipe訊號;

3 非阻塞模式下,connect返回之後,發起連線成功或失敗;

4 socket上有未處理的錯誤,此時可以用getsockopt來讀取和清除該錯誤。

在linux中,核心利用檔案描述符(file descriptor)即檔案控制代碼,來訪問檔案。檔案描述符是非負整數。開啟現存盤案或新建檔案時,核心會返回乙個檔案描述符。讀寫檔案也需要使用檔案描述符來指定待讀寫的檔案。巨集fd_zero、fd_set、fd_clr、fd_isset中「fd」即為file descriptor的縮寫,下面來一一進行介紹。

首先介紹乙個重要的結構體:fd_set,它會作為下面某些函式的引數而多次用到,fd_set可以理解為乙個集合,這個集合中存放的是檔案描述符(file descriptor),即檔案控制代碼。fd_set集合可以通過下面的巨集來進行人為來操作。

1》fd_zero

用法:fd_zero(fd_set*);

用來清空fd_set集合,即讓fd_set集合不再包含任何檔案控制代碼。

2》fd_set

用法:fd_set(int ,fd_set *);

用來將乙個給定的檔案描述符加入集合之中

3》fd_clr

用法:fd_clr(int ,fd_set*);

用來將乙個給定的檔案描述符從集合中刪除

4》fd_isset

用法:fd_isset(int ,fd_set*);

檢測fd在fdset集合中的狀態是否變化,當檢測到fd狀態發生變化時返回真,否則,返回假(也可以認為集合中指定的檔案描述符是否可以讀寫)。

5》函式select

用法:int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

作用:用來夠監視我們需要監視的檔案描述符(讀或寫的檔案集中的檔案描述符)的狀態變化情況。並能通過返回的值告知我們。

引數解釋:

int maxfdp:集合中所有檔案描述符的範圍,為所有檔案描述符的最大值加1。

fd_set *readfds:要進行監視的讀檔案集。

fd_set *writefds :要進行監視的寫檔案集。

fd_set *errorfds:用於監視異常資料。

struct timeval* timeout:select的超時時間,它可以使select處於三種狀態:

第一,若將null以形參傳入,即不傳入時間結構,就是 將select置於阻塞狀態,一定等到監視檔案描述符集合中某個檔案描述符發生變化為止;

第二,若將時間值設為0秒0毫秒,就變成乙個純粹的非阻塞函式, 不管檔案描述符是否有變化,都立刻返回繼續執行,檔案無變化返回0,有變化返回乙個正值;

第三,timeout的值大於0,這就是等待的超時時間,即 select在timeout時間內阻塞,超時時間之內有事件到來就返回了,否則在超時後不管怎樣一定返回。

struct

timeval

timeout; timeout.tv_sec = 0; //秒 timeout.tv_usec = dwtimeout * 1000; //微秒 1毫秒 = 1000微秒

返回值介紹:

>0:被監視的檔案描述符有變化

-1:出錯

0 :超時

I O多路復用

一 五種i o模型 1 阻塞i o模型 最流行的i o模型是阻塞i o模型,預設情形下,所有套介面都是阻塞的。我們以資料報套介面為例來講解此模型 我們使用udp而不是tcp作為例子的原因在於就udp而言,資料準備好讀取的概念比較簡單 要麼整個資料報已經收到,要麼還沒有。然而對於tcp來說,諸如套介面...

i o多路復用

最常見的i o多路復用就是 select poll epoll了,下面說說他們的一些特點和區別吧。select 可讀 可寫 異常三種檔案描述符集的申明和初始化。fd set readfds,writefds,exceptionfds fd zero readfds fd zero writefds ...

I O多路復用

我們都知道unix like 世界裡,一切皆檔案,而檔案是什麼呢?檔案就是一串二進位製流而已,不管socket,還是fifo 管道 終端,對我們來說,一切都是檔案,一切都是流。在資訊 交換的過程中,我們都是對這些流進行資料的收發操作,簡稱為i o操作 input and output 往流中讀出資料...