網路IO之阻塞 非阻塞 同步 非同步總結

2021-06-20 03:04:05 字數 1377 閱讀 5318

對於乙個network io(以read為例),它會涉及到兩個系統物件,乙個是呼叫該io的process(or thread),另乙個是系統核心(kernel),當乙個read操作發生時,它會經歷兩個階段

1. 等待資料準備(waiting for the data to be ready)

2. 將資料從核心拷貝到程序中(copying the data from kernel to the process)

1. blocking io

在linux中,預設情況下所有的socket都是blocking,

當使用者程序呼叫了recvfrom這個系統呼叫,kernel就開始了io的第乙個階段:準備資料。對於network io來說,很多時候資料在一開始還沒有到達(比如,還沒有收到乙個完整的udp包),這個時候kernel就要等待足夠的資料到來,而在使用者程序這邊,整個程序會被阻塞。當kernel一直等到資料準備好了,它就會將資料從kernel中拷貝到使用者記憶體,然後kernel返回結果,使用者程序才解除block的狀態,重新執行起來。

所以,blocking io的特點就是在io執行的兩個階段都被block了。

2. non-blocking io

linux下,可以通過設定socket使其變為non-blocking

當使用者程序發出read操作時,如果kernel中的資料還沒有準備好,那麼它並不會block使用者程序,而是立刻返回乙個error。從使用者角度講,它發起乙個read操作後,並不需要等待,而是馬上得到了乙個結果。使用者程序判斷結果是乙個error時,它就知道資料還沒有準備好,於是它可以再次傳送read操作。一旦kernel中的資料準備好了,並且又再次收到了使用者程序的system call,那麼它就將資料拷貝到了使用者記憶體,然後返回。

所以,使用者程序其實是需要不斷的主動詢問kernel資料好了沒有。

3. io multiplexing (select, poll, epoll) event driven io

基本原理是select/epoll這個function會不斷的輪詢所負責的所有socket,當某個socket有資料到達時,就通知使用者程序。

當使用者程序呼叫了select,整個程序就會被block,而同時,kernel會「監視」所有select負責的socket,當任何乙個socket中的資料準備好了,select就返回,這個時候使用者程序再呼叫read操作,將資料從kernel拷貝到使用者程序。

4. asynchronous io

當使用者程序發起read操作之後,立刻就可以開始去做其它的事。而另一方面,從kernel的角度,當它收到乙個asynchronous read之後,首先會立刻返回,所以不會對使用者進行產生任何block,然後,kernel會等待資料準備完成,然後將資料拷貝到使用者記憶體,當這一切都完成之後,kernel會給使用者程序傳送乙個signal,告訴它read操作完成了。

IO之同步 非同步 阻塞 非阻塞

stevens在文章中一共比較了五種io model blocking io nonblocking io io multiplexing signal driven io asynchronous io 由於signal driven io在實際中並不常用,所以我這只提及剩下的四種io model...

網路IO之阻塞 非阻塞 同步 非同步總結

1 前言 在網路程式設計中,阻塞 非阻塞 同步 非同步經常被提到。unix網路程式設計第一卷第六章專門討論五種不同的io模型,stevens講的非常詳細,我記得去年看第一遍時候,似懂非懂,沒有深入理解。網上有詳細的分析 我結合網上部落格和書總結一下,加以區別,加深理解。2 資料流向 網路io操作實際...

網路IO之阻塞 非阻塞 同步 非同步總結

1 前言 在網路程式設計中,阻塞 非阻塞 同步 非同步經常被提到。unix網路程式設計第一卷第六章專門討論五種不同的io模型,stevens講的非常詳細,我記得去年看第一遍時候,似懂非懂,沒有深入理解。網上有詳細的分析 我結合網上部落格和書總結一下,加以區別,加深理解。2 資料流向 網路io操作實際...