13 IO復用之select函式

2021-09-12 07:02:20 字數 1770 閱讀 6461

前面我們所有的**都是通過read和write操作, 每次只能處理乙個io請求. 但是io復用可以在同時處理多個socket的io請求. 而且io復用與執行緒連用是最常見的搭配.

本節介紹io多路復用select函式.

#include

#include

#include

intselect

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

struct timeval *timeout)

;

成功 : 返回事件發生的個數, 並且將返回改變的檔案符儲存在對應的集合中.

失敗 : 返回負數. 如果被中斷不可重啟, 會設定errno的值為eintr.

超時 : 返回0.

函式引數有點多, 可能一時間掌握不了可以慢慢做實驗體驗每個引數的意義.

select函式有乙個叫檔案描述符集合的資料型別fd_set,fd_set很像訊號集sigset_t而且兩者的實現都很相似.sigset_t訊號集有32位之多, 每一位表示乙個訊號. 同樣fd_set描述符集預設有1024位(最大值用fd_setsize表示), 每一位表示乙個檔案描述符.

sigset_t有一系列sigset函式,fd_set也同樣有一系列的操作函式 :

// 從描述符集中刪除fd

fd_clr

(int fd, fd_set *fdset)

;// 清除描述符集所有設定的描述符

fd_zero

(fd_set *fdset)

;// 將fd新增到描述符集中

fd_set

(int fd, fd_set *fdset)

;// 驗證fd是否在描述符集中

fd_isset

(int fd, fd_set *fdset)

;

我們使用本節介紹的select函式來修改之前的**, 實驗驗證與write函式的不同.

將客戶端的**做了修改, 這裡只將修改的**貼出分析. 完整的** select_client.c

// 客戶端

intclient

(int port,

const

char

*cli_addr)

// 4if(

fd_isset

(sockfd,

&testrfds))}

close

(sockfd)

;return0;

}

需要注意幾點

將新的描述符集zero再新增檔案描述符

因為select返回會重置所有的描述符集, 所以必須將原描述符集儲存下來, 並且每次迴圈都要重新設定

需要對每乙個操作的描述符進行判斷

最終執行的結果可以看出正常的回射任何問題, 並且服務端關閉後客戶端立馬也就關閉了.

i/o多路復用技術(multiplexing)是什麼?

I O多路復用之select

阻塞i o模型 應用程式呼叫乙個i o函式,應用程式會一直等待資料準備好。如果資料沒有準備好,就會一直等待。只有當資料準備好,從核心拷貝到使用者空間io函式才成功返回。非阻塞i o模型 把乙個套介面設定成非阻塞告訴核心,當所有的i o操作無法完成時,不要將程序睡眠,而返回乙個錯誤資訊。此時i o操作...

IO多路復用之select

1 背景知識 我們首先來看看伺服器程式設計的模型,客戶端發來的請求服務端會產生乙個程序來對其進行服務,每當來乙個客戶請求就產生乙個程序來服務,然而程序不可能無限制的產生,因此為了解決大量客戶端訪問的問題,引入了io復用技術。即 乙個程序可以同時對多個客戶請求進行服務。也就是說io復用的 介質 是程序...

redis中io復用之select

前面講過evport epoll kqueue的實現,下來我們繼續看看我們select在redis中的使用 1 首先通過fd zero來清空用於監控讀和寫fd的rfds和wfds的鍊錶 typedef struct aeapistate aeapistate static int aeapicrea...