1. 程式人生 > >python基礎27 -----python進程終結篇-----IO模型

python基礎27 -----python進程終結篇-----IO模型

非阻塞 緩存 代碼原理 linux系統 並不會 async process 而不是 拷貝數據

一、IO模型

  1、IO模型分類

    1.阻塞IO--------blocking IO

    2.非阻塞IO------nonblocking IO

    3. 多路復用IO------- multiplexing

    4.信號驅動IO-------signal driven IO (工作中不會使用到,只是作為了解)

    5.異步IO------- asynchronous IO

  2、通常情況下IO默認操作分為兩個階段(默認都是阻塞IO)

    1.準備等待數據階段,相當於請求操作系統是否有數據發送過來(調用IO操作)。

    2.將數據從內核緩存拷貝到進程緩存中。

二、不同的IO操作

  1、阻塞IO(blocking io)

    1.在Linux系統中默認情況下所有的socket都是阻塞IO,如圖所示

      技術分享

    2.阻塞IO工作原理():

      當用戶進程調用了recvfrom這個系統調用(相當於用戶進程發送請求像操作系統要數據),kernel就開始了IO的第一個階段:準備    數據。對於network io來說,很多時候數據在一開始還沒有到達,這個時候kernel就要等待足夠的數據到來。而在用戶進程這邊,整個    進程會被阻塞。當kernel一直等到數據準備好了,它就會將數據從kernel中拷貝到用戶內存,然後kernel返回結果,用戶進程才解除      block的狀態,重新運行起來。所以,blocking IO的特點就是在IO執行的兩個階段都被block了。

  2、非阻塞IO

    1.在Linux操作系統可以通過設置socket使其變為non-blocking。當對一個non-blocking socket執行讀操作時,流程是這個樣子

        技術分享

    2.非阻塞IO工作原理:

      從圖中可以看出,當用戶進程發出read操作時,如果kernel中的數據還沒有準備好,那麽它並不會block用戶進程,而是立刻返回一  個error。從用戶進程角度講 ,它發起一個read操作後,並不需要等待,而是馬上就得到了一個結果。用戶進程判斷結果是一個error時,它  就知道數據還沒有準備好,於是它可以再次發送read操作。一旦kernel中的數據準備好了,並且又再次收到了用戶進程的system call,那麽  它馬上就將數據拷貝到了用戶內存,然後返回。所以,用戶進程其實是需要不斷的主動詢問kernel數據好了沒有。如果數據還沒準備好,此  時會返回一個error。進程在接收到error後,可以幹點別的事情,然後再發起recvform系統調用。重復上面的過程,循環往復的進行recvform  系統調用。這個過程通常被稱之為輪詢。輪詢檢查內核數據,直到數據準備好,再拷貝數據到進程,進行數據處理。需要註意,拷貝數據整  個過程,進程仍然是屬於阻塞的狀態。

    3.代碼原理:

      技術分享

    3、IO多路復用

      1、以上情況只能應用於一個server處理一個客戶sock,如果想讓一個server處理多個客戶sock那就要用到IO多路復用

      2、多路復用流程圖:

        技術分享

        當用戶進程調用了select,那麽整個進程會被block,而同時,kernel會“監視”所有select負責的socket,當任何一個socket中的      數據準備好了,select就會返回。這個時候用戶進程再調用read操作,將數據從kernel拷貝到用戶進程。這個圖和blocking IO的圖      其實並沒有太大的不同,事實上,還更差一些。因為這裏需要使用兩個system call (select 和 recvfrom),而blocking IO只調用了一      個system call (recvfrom)。但是,用select的優勢在於它可以同時處理多個connection,在IO multiplexing Model中,實際中,對於      每一個socket,一般都設置成為non-blocking,但是,如上圖所示,整個用戶的process其實是一直被block的。只不過process是被      select這個函數block,而不是被socket IO給block。

      3.代碼實現原理:

        技術分享

      4、利用selectors來實現IO的多路復用

        技術分享

      5、註釋:在windows下只支持python中的select阻塞,而在linux下是三者都支持。我們通過selectors模塊python可以自動判斷

      使用什麽阻塞方式。

    技術分享

     6、各個IO模型比較圖:

        技術分享

  

python基礎27 -----python進程終結篇-----IO模型