自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

unix下的I/O------阻塞,非阻塞,同步,異步

系統(tǒng) 其他OS
前4種模型的主要區(qū)別在于第一階段,因?yàn)樗鼈兊牡诙A段都是一樣的:在數(shù)據(jù)從內(nèi)核緩沖區(qū)拷貝到進(jìn)程緩沖區(qū)期間,進(jìn)程阻塞與recvfrom這個系統(tǒng)調(diào)用中。

參考 Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking”。

Stevens一共提出了五種 IO Model:

  • blocking IO
  • nonblocking IO
  • IO multiplexing (select and poll)
  • signal driven IO (SIGIO)
  • asynchronous IO (the POSIX aio_functions)

先說一下IO發(fā)生時所涉及的對象和步驟。

一個輸入操作通常包括下面兩個階段:

  1. 等待數(shù)據(jù)準(zhǔn)備好 (Waiting for the data to be ready)。對于一個套接口上的輸入操作,通常涉及等待數(shù)據(jù)從網(wǎng)絡(luò)到達(dá),到達(dá)后它被拷貝到內(nèi)核的某個緩沖區(qū)。
  2. 將數(shù)據(jù)從內(nèi)核緩存區(qū)拷貝到進(jìn)程緩沖區(qū)中 (Copying the data from the kernel to the process)

記住這兩個階段很重要,因?yàn)橐韵乱懻摰奈宸NIO Model的區(qū)別就是在兩個階段上各有不同的情況。

Blocking I/O Model(阻塞I/O)

默認(rèn)情況下所有的套接口都是blocking。

進(jìn)程調(diào)用recvfrom,其系統(tǒng)調(diào)用直到數(shù)據(jù)報到達(dá)(第一階段)且被拷貝到應(yīng)用進(jìn)程的緩沖區(qū)中(第二階段)或者發(fā)生錯誤(最常見的錯誤是系統(tǒng)調(diào)用被信號中斷)才返回。進(jìn)程在從調(diào)用recvfrom開始到它返回的整個過程是被阻塞的。 recvfrom成功返回后,應(yīng)用進(jìn)程開始處理數(shù)據(jù)報。

Nonblocking I/O Model(非阻塞I/O)

前三次調(diào)用recvfrom時數(shù)據(jù)還沒準(zhǔn)備好,這是內(nèi)核立即返回一個EWOULDBLOCK錯誤。第四次調(diào)用recvfrom時數(shù)據(jù)已準(zhǔn)備好,它被拷貝到應(yīng)用進(jìn)程緩沖區(qū),recvfrom接著成功返回,然后應(yīng)用進(jìn)程開始處理數(shù)據(jù)報。

這里最關(guān)鍵的一個操作就是輪詢(polling)。應(yīng)用進(jìn)程持續(xù)輪詢內(nèi)核,以查看數(shù)據(jù)是否就緒。這樣做往往會耗費(fèi)大量的CPU時間,這種模型通常會在專門提供某種功能的系統(tǒng)才有。

I/O Multiplexing Model(I/O復(fù)用模型)

當(dāng)用戶進(jìn)程調(diào)用了select,那么整個進(jìn)程會被block,而同時,kernel會“監(jiān)視”所有select負(fù)責(zé)的socket,當(dāng)任何一個socket中的數(shù)據(jù)準(zhǔn)備好了,select就會返回套接字可讀這個條件,我們調(diào)用recvfrom把所讀數(shù)據(jù)報拷貝到應(yīng)用程序進(jìn)程緩沖區(qū)。

和blocking IO的圖比較,I/O復(fù)用并沒有顯示出什么優(yōu)勢。事實(shí)上,可能稍有劣勢。因?yàn)檫@里需要使用兩個system call (select 和 recvfrom),而blocking IO只調(diào)用了一個system call。但是,用select的優(yōu)勢在于它可以同時處理多個connection。

Signal-Driven I/O Model(信號驅(qū)動I/O模型)

我們首先開啟套接口的信號驅(qū)動I/O功能,并通過sigaction系統(tǒng)調(diào)用安裝一個信號處理函數(shù)。該系統(tǒng)調(diào)用將立即返回,我們的進(jìn)程這是并沒有被阻塞,而是繼續(xù)執(zhí)行。當(dāng)數(shù)據(jù)報準(zhǔn)備好讀取時,內(nèi)核就為該進(jìn)程產(chǎn)生一個SIGIO信號。我們隨后既可以在信號處理函數(shù)中調(diào)用recvfrom讀取數(shù)據(jù)報,并通知主循環(huán)數(shù)據(jù)已準(zhǔn)備好待處理,也可以立即通知主循環(huán),讓它來讀取數(shù)據(jù)報。無論如何處理SIGIO信號,這種模型的優(yōu)勢在于等待數(shù)據(jù)報到達(dá)(第一階段)期間,進(jìn)程可以繼續(xù)執(zhí)行,不被阻塞。

Asynchronous I/O Model(異步I/O模型)

進(jìn)程發(fā)起read操作之后,立刻就可以開始去做其它的事。而另一方面,從kernel的角度,當(dāng)它受到一個asynchronous read之后,首先它會立刻返回,所以不會對用戶進(jìn)程產(chǎn)生任何block。然后,kernel會等待數(shù)據(jù)準(zhǔn)備完成,然后將數(shù)據(jù)拷貝到用戶內(nèi)存,當(dāng)這一切都完成之后,kernel會給用戶進(jìn)程發(fā)送一個signal,告訴它read操作完成了。

這個模型工作機(jī)制是:告訴內(nèi)核啟動某個操作,并讓內(nèi)核在整個操作(包括第二階段,即將數(shù)據(jù)從內(nèi)核拷貝到進(jìn)程緩沖區(qū)中)完成后通知我們。

這種模型和前一種模型區(qū)別在于:信號驅(qū)動I/O是由內(nèi)核通知我們何時可以啟動一個I/O操作,而異步I/O模型是由內(nèi)核通知我們I/O操作何時完成。

五種I/O模型介紹完了,下面來說說blocking和non-blocking的區(qū)別在哪,synchronous IO和asynchronous IO的區(qū)別在哪。

blocking I/Ovs non-blocking I/O :調(diào)用blocking IO會一直block住對應(yīng)的進(jìn)程直到操作完成,而non-blocking IO在kernel還準(zhǔn)備數(shù)據(jù)的情況下會立刻返回。

synchronous I/O vs asynchronous I/O:

先看看這兩個定義:

A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes;

An asynchronous I/O operation does not cause the requesting process to be blocked;

兩者的區(qū)別就在于synchronous IO做”IO operation”的時候會將process阻塞。按照這個定義,之前所述前四種模型blocking I/O,non-blocking I/O,IO multiplexing,signal driven IO都屬于synchronous IO。有人可能會說,non-blocking IO并沒有被block啊。這里有個非常“狡猾”的地方,定義中所指的”IO operation”是指真實(shí)的IO操作,就是例子中的recvfrom這個system call。non-blocking IO在執(zhí)行recvfrom這個system call的時候,如果kernel的數(shù)據(jù)沒有準(zhǔn)備好,這時候不會block進(jìn)程。但是,當(dāng)kernel中數(shù)據(jù)準(zhǔn)備好的時候,recvfrom會將數(shù)據(jù)從 kernel拷貝到用戶內(nèi)存中,這個時候(第二階段)進(jìn)程是被block了,在這段時間內(nèi),進(jìn)程是被block的。而asynchronous IO則不一樣,當(dāng)進(jìn)程發(fā)起IO 操作之后,就直接返回再也不理睬了,直到kernel發(fā)送一個信號,告訴進(jìn)程說IO完成。在這整個過程中,進(jìn)程完全沒有被block。

各個IO Model的比較如圖所示:

前4種模型的主要區(qū)別在于第一階段,因?yàn)樗鼈兊牡诙A段都是一樣的:在數(shù)據(jù)從內(nèi)核緩沖區(qū)拷貝到進(jìn)程緩沖區(qū)期間,進(jìn)程阻塞與recvfrom這個系統(tǒng)調(diào)用中。

責(zé)任編輯:艾婧 來源: welbeckxu的博客
相關(guān)推薦

2018-03-28 08:52:53

阻塞非阻塞I

2019-07-23 11:01:57

Python同步異步

2012-10-10 10:00:27

同步異步開發(fā)Java

2015-07-03 10:12:04

編程同步非阻塞

2024-09-23 17:15:28

Python并發(fā)并行

2024-11-26 10:37:19

2023-07-31 08:55:01

Java NIO非阻塞阻塞

2021-06-04 18:14:15

阻塞非阻塞tcp

2021-03-04 08:34:55

同步阻塞非阻塞

2021-10-13 06:49:15

網(wǎng)絡(luò) IO

2021-02-27 16:08:17

Java異步非阻塞

2022-06-22 08:16:29

異步非阻塞框架

2023-12-06 07:28:47

阻塞IO異步IO

2024-08-05 09:16:54

2019-05-05 08:50:42

阻塞非阻塞BIO

2025-02-17 13:23:34

Python同步阻塞MySQL

2016-11-28 09:08:43

java系統(tǒng)異步非阻塞

2017-03-01 16:40:12

Linux驅(qū)動技術(shù)設(shè)備阻塞

2021-01-10 11:21:33

JavaScript語言開發(fā)

2022-09-22 10:51:32

服務(wù)端開發(fā)者異步非阻塞編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號