select函式socket程式設計

amadan發表於2021-09-09

套接字程式設計中的select函式是一個比較重要的概念,是epoll函式的早期版本,是實現I/O複用的關鍵方法。在對這個方法的瞭解過程中,走了一些彎路,由於select一直與併發,非同步等字眼聯絡在一起,總覺得select是不阻塞的,事實上它本身是阻塞的。當我苦苦在網上搜尋答案卻相互矛盾的時候,我知道是時候冷靜下來喝一口水,思考自己是否還適合幹這一行。不對,是是時候找一本權威的書籍翻閱一下了。

阻塞I/O模型

首先需要了解的是socket阻塞的概念,我們知道socket的讀寫操作並不是直接向網路中讀寫,而是向本地的網路緩衝區中讀寫,每一個socket會被分配一個讀和一個寫緩衝區,如果當我們希望讀取資料,但是緩衝區中還沒有資料的時候,那麼讀方法(recv)會被阻塞知道有足夠的資料可以接受,那麼這個過程中程式會被阻塞,你的程式不能幹別的,只能等。在《UNIX網路程式設計》一書中,用這樣的圖來表示這個過程。


圖片描述

image.png

I/O複用模型

第二個需要了解的概念是I/O複用,因為select,包括poll和epoll都是實現這種模型的機制,我不明白為什麼要叫I/O複用,但是它的好處是程式阻塞與select函式,而不是阻塞於真正的I/O系統呼叫,那麼這個過程同樣書中描述為


圖片描述

image.png


看兩張圖,好像複用並沒有什麼優越性,因為它同樣要阻塞等待直到在監聽的socket列表中有socket讀或寫操作返回。時間上好像並沒有什麼差別。

select的優越性

select的優越性主要表現在它可以實現一個執行緒監聽多個socket控制程式碼,而阻塞模型則需要多執行緒來達到這個目的,所以在併發的大量請求的情況下,這樣是能節省很多開銷的。還有在設定好timeout後,超過這個時間select將不再阻塞,會返回錯誤,這樣可以接著執行別的操作,一定程度上能達到非同步的目的。所以你看,這樣就和併發和非同步聯絡上了。



作者:Spring_Bear
連結:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2310/viewspace-2819289/,如需轉載,請註明出處,否則將追究法律責任。

相關文章