python模組之io
一 IO模型 分為:
1 阻塞IO (accept recv)
2 非阻塞IO
3 IO多路複用(監聽多個連結)
4 非同步IO
5 驅動訊號模型(不經常使用)
1 阻塞IO (blocking IO)
特點:全程阻塞(程序不能幹其他的事兒)
當用戶程序呼叫了recvfrom這個系統呼叫,kernel就開始了IO的第一個階段:準備資料。對於network io來說,很多時候資料在一開始還沒有到達,這個時候kernel就要等待足夠的資料到來,而在使用者程序這邊,整個程序會被阻塞。
當kernel直等到資料準備好了,他就會將資料從kernel中拷貝到使用者記憶體,然後kernel返回結果,使用者程序才解除block的狀態,重新執行起來。
2 非阻塞IO(non-blocking IO)
特點:傳送多次系統呼叫
優點:wait for data時無阻塞
缺點:多次系統呼叫,消耗,不能第一時間拿取資料
兩個階段:wait for data非阻塞
cope data是阻塞的
注意:在網路IO時候,非阻塞IO也會進行recvfrom系統呼叫,檢查資料是否準備好,與阻塞IO不一樣,”非阻塞將大的整片時間的阻塞分成N多的小的阻塞,所以程序不斷地有機會’被CPU光顧’”。即每次recvfrom系統呼叫之間,cpu的許可權還在程序手中,這段時間可以做其他事情。
也就是說非 阻塞的recvfrom系統呼叫,程序並沒有被阻塞,核心馬上返回給程序,如果資料還沒有準備好,此時會返回一個error。程序在返回之後,可以乾點別的事情,然後在發起recvfrom系統呼叫,重複上面的過程。不斷重複進行recvfrom系統呼叫,這個過程被稱為輪詢,輪詢檢查核心資料,直到資料被準備好,再拷貝資料到程序,進行資料處理,需要注意,拷貝資料整個過程,程序仍然是屬於阻塞的狀態。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
3 IO多路複用(IO multiplexing)
特點:1全程阻塞(wait for data, copy data)
2 能監聽多個檔案描述符
實現併發
select, epoll,poll
select發起系統呼叫(監聽多個連線 實行併發)
對於檔案描述符(套接字物件):
1 是一個非零整數,不會變
2 收發資料的時候,對於接收端而言,資料先到核心空間,然後通過copy到使用者空間,同時,核心空間資料清空。
IO multiplexing這個詞可能有點陌生,但是如果說select,epoll,大概就都能明白了,有些地方也稱這用IO方式為event driven IO。我們知道,select/epoll的好處就在於單個process就可以同時處理多個網路連線的IO,它的基本原理就是selet/epoll這個function會不斷的輪詢所有的socket,當某個socket有資料到達了,就通知使用者程序。
當用戶程序呼叫了select,那麼整個程序會被block,而同時,kernel會”監視”所有select負責的socket,當任何一個socket中的資料準備好了,select就回返回。這個時候使用者程序再呼叫read操作,將資料從kernel拷貝到使用者程序。
需要使用兩個system call(select和recvfrom),而blocking IO只調用了一個system call(recvfrom)。
注意1:select函式返回結果中如果有檔案可讀了,那麼程序就可以通過呼叫accept()或recv()
來讓kernel將位於核心中準備到資料copy到使用者區。
注意2:select的優勢在於可以處理多個連線,不適用於單個連線
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
4 非同步IO(Asynchronous I/O)
特點:全程無阻塞
使用者程序發起read操作之後,立刻就可以開始去做其他的事兒,從另一方面,從kernel的角度,當它收到一個asynchronous read 之後,首先它會立刻返回,所以不會對使用者程序產生任何block,然後,kernel會 資料準備完成 ,然後將資料拷貝到使用者記憶體,當著一切都完成之後,kernel就給使用者程序傳送一個signal,告訴它read操作完成了。
同步阻塞:包括(阻塞IO,非阻塞IO,IO多路複用)
非同步阻塞:無阻塞 包括(非同步IO)
各個IO Model的比較如果所示: