I O多路復用之select系統呼叫

2021-07-29 13:15:02 字數 1888 閱讀 7377

i/o多路復用模型允許我們同時等待多個套接字描述符是否就緒。linux系統為實現i/o多路復用提供的最常見的乙個函式是select函式,該函式允許程序指示核心等待多個事件中的任何乙個發生,並只有在乙個或多個事件發生或經歷一段指定的時間後才喚醒它。

作為乙個例子,我們可以呼叫select,告知核心僅在下列情況發生時才返回:

也就是說,我們呼叫select可以告知核心我們對哪些描述符感興趣以及等待多久時間。

select是乙個複雜的函式,有許多不同的應用場景,我們將只討論第一種場景:等待一組描述符準備好讀。

#include 

#include

int select(int n, fd_set *fdset, null, null, struct timeval *timeout);

fd_zero(fd_set *fdset); // 將fdset初始為為空集合

fd_clr(int fd, fd_set *fdset); // 從fdset清除fd

fd_set(int fd, fd_set *fdset); // 將fd新增到fdset

fd_isset(int fd, fd_set *fdset); // fd是否存在於fdset

我們來看下select函式的引數。引數n指定需要測試的描述符的數目,測試的描述符範圍從0到n-1。第二個引數fdset指定需要測試的可讀描述符集合。當fdset集合中有描述符可讀,或者經歷了timeout時間時,select將返回。當select返回時,作為乙個***,select修改了引數fdset指向的描述符集合,這時fdset變成由讀集合中準備好可以讀了的描述符組成。select函式的返回值則指明了就緒集合的基數。值得注意的是,由於這個***,我們必須每次在呼叫select時都更新讀集合。

#include 

#include

#include

#include

#include

#include

#include

#include

int main()

for (fd = 0; fd < fd_setsize; fd++)

// 如果是舊的客戶活動

else

// 客戶請求資料到達

else }}

}}

}

上面的**展示了如何使用select來編寫多併發伺服器的過程。伺服器可以讓select呼叫同時檢查監聽套接字和已連線套接字。一旦select指示有活動發生,就可以用fd_isset來遍歷所有可能的檔案描述符,以檢查是哪個描述符上面有活動發生。

如果是監聽套接字可讀,這說明正有乙個客戶試圖建立連線,此時就可以呼叫accept建立乙個客戶的已連線套接字而不用擔心阻塞。如果是某個客戶描述符準備好,這說明該描述符上有乙個客戶請求需要我們讀取處理。如果讀操作返回零位元組,這表示有乙個客戶程序已結束,這時我們可以關閉該套接字並把它從描述符集合中刪除。

深入理解計算機系統,第2版,機械工業出版社

linux程式設計(第4版),neil matthew等著,人民郵電出版社,2023年

unix 網路程式設計卷1:套接字聯網api(第三版), w.richard stevens 等著

I O多路復用之select

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

IO多路復用之select

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

I O多路復用之select

select是用於監視多個檔案描述符狀態的變化的。即用來監視檔案描述符讀 寫 異常狀態是否就緒。函式原型 int select int nfds,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout select...