阻賽與非阻塞詳解_第1頁
阻賽與非阻塞詳解_第2頁
阻賽與非阻塞詳解_第3頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、阻賽與非阻塞詳解同步( synchronous) IO 和異步( asynchronous) IO , 阻塞( blocking ) IO 和非阻塞( non-blocking ) IO 分別是什 么,到底有什么區(qū)別?這個(gè)問題其實(shí)不同的人給出的答案都 可能不同,比如 wiki ,就認(rèn)為 asynchronous IO 和 non-blocking IO 是一個(gè)東西。 這其實(shí)是因?yàn)椴煌娜说闹R(shí)背景不同, 并 且在討論這個(gè)問題的時(shí)候上下文(context) 也不相同。所以,為了更好的回答這個(gè)問題,我先限定一下本文的上下文。 本文討論的背景是 Linux 環(huán)境下的 network IO 。本文最重

2、要的參考文獻(xiàn)是Richard Stevens的“ UNIX? NetworkProgramming Volume 1, Third Edition: The Sockets Networking ”,6.2 節(jié)“ I/O Models ”,Stevens 在這節(jié)中詳細(xì) 說明了各種 IO 的特點(diǎn)和區(qū)別,如果英文夠好的話,推薦直 接閱讀。Stevens的文風(fēng)是有名的深入淺出,所以不用擔(dān)心看不懂。本文中的流程圖也是截取自參考文獻(xiàn)。Stevens在文章中一共比較了五種 IO Model :blocking IO nonblocking IO IO multiplexing signal driven

3、IO asynchronous IO由于 signal driven IO 在實(shí)際中并不常用,所以我這只提及剩 下的四種 IO Model 。再說一下 IO 發(fā)生時(shí)涉及的對(duì)象和步驟。 對(duì)于一個(gè)network IO (這里我們以read舉例),它會(huì)涉及到兩 個(gè)系統(tǒng)對(duì)象,一個(gè)是調(diào)用這個(gè) 10的process (or thread),另一 個(gè)就是系統(tǒng)內(nèi)核(kernel)。當(dāng)一個(gè)read操作發(fā)生時(shí),它會(huì)經(jīng)歷 兩個(gè)階段:1 等待數(shù)據(jù)準(zhǔn)備 (Waiting for the data to be ready)2 將數(shù)據(jù)從內(nèi)核拷貝到進(jìn)程中 (Copying the data from the kernel t

4、o the process)記住這兩點(diǎn)很重要, 因?yàn)檫@些 IO Model 的區(qū)別就是在兩個(gè)階 段上各有不同的情況。 信號(hào)驅(qū)動(dòng) I/O 兩次調(diào)用,兩次返回。 安裝信號(hào)處理函數(shù),進(jìn)程繼續(xù)運(yùn)行不阻賽。數(shù)據(jù)準(zhǔn)備好時(shí)收 到一個(gè) SIGIO 信號(hào),進(jìn)而調(diào)用 I/O 操作函數(shù)。 blocking IO 在linux中,默認(rèn)情況下所有的 socket都是blocking,一個(gè)典 型的讀操作流程大概是這樣: 當(dāng)用戶進(jìn)程調(diào)用了 recvfrom 這 個(gè)系統(tǒng)調(diào)用, kernel 就開始了 IO 的第一個(gè)階段:準(zhǔn)備數(shù)據(jù)。 對(duì)于 network io 來說,很多時(shí)候數(shù)據(jù)在一開始還沒有到達(dá) (比 如,還沒有收到一個(gè)完整

5、的 UDP 包),這個(gè)時(shí)候 kernel 就要 等待足夠的數(shù)據(jù)到來。而在用戶進(jìn)程這邊,整個(gè)進(jìn)程會(huì)被阻 塞。當(dāng) kernel 一直等到數(shù)據(jù)準(zhǔn)備好了, 它就會(huì)將數(shù)據(jù)從 kernel 中拷貝到用戶內(nèi)存,然后 kernel 返回結(jié)果,用戶進(jìn)程才解除 block 的狀態(tài),重新運(yùn)行起來。所以, blocking IO 的特點(diǎn)就是在 IO 執(zhí)行的兩個(gè)階段都被 block 了。 non-blocking IOlinux 下,可以通過設(shè)置 socket 使 其變?yōu)?non-blocking 。當(dāng)對(duì)一個(gè) non-blocking socket 執(zhí)行讀操 作時(shí),流程是這個(gè)樣子:從圖中可以看出,當(dāng)用戶進(jìn)程發(fā)出 rea

6、d 操作時(shí),如果 kernel 中的數(shù)據(jù)還沒有準(zhǔn)備好,那么它并 不會(huì)block用戶進(jìn)程,而是立刻返回一個(gè)error。從用戶進(jìn)程角度講 ,它發(fā)起一個(gè) read 操作后,并不需要等待,而是馬 上就得到了一個(gè)結(jié)果。用戶進(jìn)程判斷結(jié)果是一個(gè)error時(shí),它就知道數(shù)據(jù)還沒有準(zhǔn)備好,于是它可以再次發(fā)送 read 操作。 一旦 kernel 中的數(shù)據(jù)準(zhǔn)備好了,并且又再次收到了用戶進(jìn)程 的system call,那么它馬上就將數(shù)據(jù)拷貝到了用戶內(nèi)存,然 后返回。所以,用戶進(jìn)程其實(shí)是需要不斷的主動(dòng)詢問 kernel 數(shù)據(jù)好了 沒有。 IO multiplexingIO multiplexing 這個(gè)詞可能有點(diǎn)陌生,

7、 但是如果我說 select, epo l l ,大概就都能明白了。有些地方 也稱這種 IO 方式為 event driven IO 。我們都知道, select/epoll 的好處就在于單個(gè) process就可以同時(shí)處理多個(gè)網(wǎng)絡(luò)連接的10。它的基本原理就是select/epoll這個(gè)function會(huì)不斷的輪詢所負(fù)責(zé)的所有socket,當(dāng)某個(gè)socket有數(shù)據(jù)到達(dá)了,就通 知用戶進(jìn)程。它的流程如圖:當(dāng)用戶進(jìn)程調(diào)用了select,那么整個(gè)進(jìn)程會(huì)被 block,而同時(shí),kernel會(huì)“監(jiān)視”所有select 負(fù)責(zé)的socket,當(dāng)任何一個(gè)socket中的數(shù)據(jù)準(zhǔn)備好了,select 就會(huì)返回。這個(gè)

8、時(shí)候用戶進(jìn)程再調(diào)用 read 操作,將數(shù)據(jù)從kernel 拷貝到用戶進(jìn)程。這個(gè)圖和 blocking IO 的圖其實(shí)并沒有太大的不同,事實(shí)上, 還更差一些。因?yàn)檫@里需要使用兩個(gè) system call (select 和 recvfrom) ,而 blocking IO 只調(diào)用了一個(gè) system call (recvfrom) 。但是,用 select 的優(yōu)勢(shì)在于它可以同時(shí)處理多個(gè) connection。(多說一句。所以,如果處理的連接數(shù)不是很高 的話,使用 select/epoll 的 web server 不一定比使用 multi-threading + blocking 10 的 we

9、b server 性能更好, 可能延 遲還更大。 select/epoll 的優(yōu)勢(shì)并不是對(duì)于單個(gè)連接能處理得 更快,而是在于能處理更多的連接。 )在 I0 multiplexing Model 中,實(shí)際中,對(duì)于每一個(gè) socket, 一般都設(shè)置成為 non-blocking ,但是,如上圖所示,整個(gè)用 戶的process其實(shí)是一直被 block的。只不過process是被select 這個(gè)函數(shù) block ,而不是被 socket I0 給 block。 Asynchronous I/0linux 下的 asynchronous I0 其實(shí)用得很少。先看一下它的 流程:用戶進(jìn)程發(fā)起 read

10、操作之后, 立刻就可以開始去做其 它的事。而另一方面,從 kernel 的角度,當(dāng)它受到一個(gè) asynchronous read之后,首先它會(huì)立刻返回,所以不會(huì)對(duì)用 戶進(jìn)程產(chǎn)生任何block。然后,kernel會(huì)等待數(shù)據(jù)準(zhǔn)備完成, 然后將數(shù)據(jù)拷貝到用戶內(nèi)存,當(dāng)這一切都完成之后, kernel會(huì)給用戶進(jìn)程發(fā)送一個(gè)signal,告訴它read操作完成了。到 目前為止, 已經(jīng)將四個(gè) IO Model 都介紹完了。 現(xiàn)在回過頭來 回答最初的那幾個(gè)問題: blocking 和 non-blocking 的區(qū)別在 哪, synchronous IO 和 asynchronous IO 的區(qū)別在哪。 先回答

11、最簡單的這個(gè): blocking vs non-blocking 。前面的介紹 中其實(shí)已經(jīng)很明確的說明了這兩者的區(qū)別。調(diào)用 blocking IO 會(huì)一直 block 住對(duì)應(yīng)的進(jìn)程直到操作完成, 而 non-blocking IO 在 kernel 還準(zhǔn)備數(shù)據(jù)的情況下會(huì)立刻返回。在說明 synchronous IO 和 asynchronous IO 的區(qū)別之前,需要先給出 兩者的定義。 Stevens 給出的定義(其實(shí)是 POSIX 的定義) 是這樣子的:A synchronous I/O operation causes the requesting process to be block

12、ed until that I/O operationcompletes;An asynchronous I/O operation does not cause the requesting process to be blocked;兩者的區(qū)別就在于 synchronous IO 做” IO operation ”的時(shí)候 會(huì)將process阻塞。按照這個(gè)定義,之前所述的blocking 10 ,non-blocking IO , IO multiplexing 都屬于 synchronous IO。有 人可能會(huì)說, non-blocking I0 并沒有被 block 啊。這里有個(gè) 非?!?/p>

13、狡猾”的地方,定義中所指的”IO operation ”是指真實(shí)的 IO 操作,就是例子中的 recvfrom 這個(gè) system call。 non-blocking IO 在執(zhí)行 recvfrom 這個(gè) system call 的時(shí)候,如 果 kernel 的數(shù)據(jù)沒有準(zhǔn)備好, 這時(shí)候不會(huì) block 進(jìn)程。 但是, 當(dāng) kernel 中數(shù)據(jù)準(zhǔn)備好的時(shí)候, recvfrom 會(huì)將數(shù)據(jù)從 kernel 拷貝到用戶內(nèi)存中,這個(gè)時(shí)候進(jìn)程是被 block 了,在這段時(shí) 間內(nèi),進(jìn)程是被 block 的。而 asynchronous IO 則不一樣,當(dāng) 進(jìn)程發(fā)起 IO 操作之后,就直接返回再也不理睬了,

14、直到 kernel 發(fā)送一個(gè)信號(hào), 告訴進(jìn)程說 IO 完成。在這整個(gè)過程中, 進(jìn)程完全沒有被 block 。各個(gè) IO Model 的比較如圖所示:經(jīng) 過上面的介紹, 會(huì)發(fā)現(xiàn) non-blocking IO 和 asynchronous IO 的 區(qū)別還是很明顯的。在 non-blocking IO 中,雖然進(jìn)程大部分 時(shí)間都不會(huì)被 block ,但是它仍然要求進(jìn)程去主動(dòng)的 check, 并且當(dāng)數(shù)據(jù)準(zhǔn)備完成以后,也需要進(jìn)程主動(dòng)的再次調(diào)用 recvfrom 來將數(shù)據(jù)拷貝到用戶內(nèi)存。 而 asynchronous IO 則完 全不同。它就像是用戶進(jìn)程將整個(gè) IO 操作交給了他人 ( kernel )完成,然后他人做完后發(fā)信號(hào)通知。在此期間, 用戶進(jìn)程不需要去檢查 IO 操作的狀態(tài),也不需要主動(dòng)的去 拷貝數(shù)據(jù)。最后,再舉幾個(gè)不是很恰當(dāng)?shù)睦觼碚f明這四個(gè) IO Model:有

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論