1. 程式人生 > >Python並發編程之IO模型

Python並發編程之IO模型

完整 span lin 結果 ext mod 是什麽 返回 image

一:IO模型介紹

同步(synchronous) IO和異步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分別是什麽,到底有什麽區別?這個問題其實不同的人給出的答案都可能不同,比如wiki,就認為asynchronous IO和non-blocking IO是一個東西。這其實是因為不同的人的知識背景不同,並且在討論這個問題的時候上下文(context)也不相同。所以,為了更好的回答這個問題,我先限定一下本文的上下文。

本文討論的背景是Linux環境下的network IO。本文最重要的參考文獻是Richard Stevens的“UNIX? Network Programming Volume 1, Third Edition: The Sockets Networking ”,6.2節“I/O Models ”,Stevens在這節中詳細說明了各種IO的特點和區別,如果英文夠好的話,推薦直接閱讀。Stevens的文風是有名的深入淺出,所以不用擔心看不懂。本文中的流程圖也是截取自參考文獻。

為了更好的了解IO模型,我們需要知道:同步,異步,阻塞,非阻塞。(contex)

同步(synchronous):

異步(asynchronous):

阻塞(blocking)

非阻塞(non-blocking)

對於一個network IO(以read舉例),他會涉及到兩個系統對象,一個是調用這個IO的process(or thread),另一個就是系統內核(kernel)。當一個read操作發生時,該操作會經歷連個階段:

1:等待數據(waiting for the data to be readg)

2:將數據從內核拷貝到進程中(Copying the data from the kernel to the process)

二:阻塞IO(bloking IO)

在Linux中,在默認情況下所有的socket都是blocking。

技術分享

當用戶進程調用了recvfrom這個系統調用,kernel就開始了IO的第一個階段:準備數據。對於network io來說,很多時候數據在一開始還沒有到達(比如,還沒有收到一個完整的UDP包),這個時候kernel就要等待足夠的數據到來。

而在用戶進程這邊,整個進程會被阻塞。當kernel一直等到數據準備好了,它就會將數據從kernel中拷貝到用戶內存,然後kernel返回結果,用戶進程才解除block的狀態,重新運行起來。

Python並發編程之IO模型