為什麼Linux的IO多路復用技術需要用非堵塞IO

2021-10-08 15:25:53 字數 1012 閱讀 3665

1、對於read操作。當緩衝區有資料時,堵塞io與非堵塞io都是能讀多少資料就讀多少資料讀完立即返回,返回值為讀取到的位元組數。當緩衝區為空時,對於堵塞io會堵塞住,cpu會切換給其他程序或者執行緒;對於非堵塞io,read函式會返回-1並且設定錯誤碼為eagian或者ewouldblock。

2、對於write操作。當緩衝區足夠容納要寫入資料時,堵塞與非堵塞io都會把全部資料都寫入緩衝區後立即返回,返回值為寫入的大小。當緩衝區不足時,對於堵塞io,write操作會堵塞住,cpu切換給其他程序或者執行緒,直到全部資料都寫入為止,函式返回寫入的大小,但是如果對端傳送了rst報文關閉連線或者超時等錯誤,那麼write函式立即返回,返回寫入的資料大小,如果再次呼叫write函式,會返回-1,更新錯誤碼;對於非堵塞io,write函式會寫入能寫入的資料,返回寫入的大小,如果緩衝區不能寫入任何資料,則返回-1並且更新錯誤碼為eagain或者ewoldblock。

3、對於監聽套接字。當已連線佇列有連線的socket時,堵塞與非堵塞io呼叫accept函式都會返回已連線的socket。當已連線隊列為空時,對於堵塞io會堵塞在accept函式,直到有新的連線建立,cpu切換給其他程序或者執行緒;對於非堵塞io,accept函式會返回-1並且更新錯誤碼為eagain或者ewoldblock。

4、對於客戶端的connect。對於堵塞io會堵塞在connect函式的呼叫上,直到三次握手完成連線建立成功,connect返回0;對於非堵塞io,connect函式會立即返回-1更新錯誤碼為einprogress,linux核心會繼續完成三次握手,應用程式可以用select,poll,epoll的io復用技術獲取連線成功事件。

場景一:客戶端設定如下的選項:

struct linger ling;

ling.l_onoff = 1;

ling.l_linger = 0;

setsockopt(socket_fd, sol_socket, so_linger, &ling, sizeof(ling));

close(socket_fd);

IO多路復用的引出(為什麼要用IO多路復用)

程序數量有限 代價太高 銷毀,上下文切換 受限於cpu 記憶體隔離 程序間通訊代價高 以上都是不可避免的的 受限於cpu 那麼影響的是響應能力 例如1000個執行緒都在發收 全部排程,響應能力肯定受影響 阻塞那麼會有同學說改為非阻塞不就行了嗎?那麼改為非阻塞不能完成收發資訊就會結束,那麼迴圈檢測 e...

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 ...