Python-異步編程
1、異步 同步
函數或方法被調用時,調用者是否得到最終的結果
直接得到最終結果的,就是同步調用
不直接得到最終結果的,就是異步調用
2、阻塞 非阻塞
函數或方法調用的時候,是否立刻返回
立即返回就是非阻塞
不立即返回就是阻塞調用
3、區別
同步,異步,與 阻塞,非阻塞 沒有關系
同步,異步強調的是,是否得到最終的結果。
阻塞,非阻塞強調的是時間,是否等待
同步與異步區別在於:調用者是否得到了想要的結果
同步就是一直要執行到返回最終的結果
異步就是直接返回額,但是返回的不是最終的結果,調用者不能通過這種嗲用得到結果,需要童工被調用者的其他方式通知調用者,來取回最終結果。
阻塞與非阻塞 的區別在於,調用者是否還能幹其他的事
阻塞,調用者就只能幹等
非阻塞,調用者可以先去忙別的,不用一直等。
4、聯系
同步阻塞:什麽都不做,直到拿到最終的結果
同步非阻塞:等最終結果的期間,可以做別的
異步阻塞:給一個信息,讓等通知,但是期間什麽都不幹
異步非阻塞:等通知,但是期間可以做別的
5、同步IO,異步IO,IO 多路復用
5.1、IO 兩個階段:
1、數據準備階段
2、內核空間復制數據到用戶進程緩沖區階段
5.2、發生IO的時候:
1、內核從輸入設備讀,寫數據
2、進程從內核復制數據
系統調用 ---- read 函數
6、IO 模型
同步IO:
同步IO 模型包括:阻塞IO,非阻塞IO, IO多路復用
***阻塞IO:
進程等待(阻塞),知道讀寫完成(全程等待)
read/ write 函數
****非阻塞IO
進程調用read操作,如果IO設備沒有準備好,立即返回error ,進程不阻塞,用戶可以再次發起系統調用,如果內核已經準備好,就阻塞,然後復制數據到用戶空間。
第一階段數據沒有準備好,就先忙別的,等會再來看看,檢查數據是否準備好了的過程是非阻塞的。
第二階段是阻塞的,即內核空間和用戶空間之間復制數據 是阻塞的。
****IO 多路復用
所謂IO 多路復用,就是同事監控多個IO,有一個準備好了,就不需要等了,開始處理,提高了同時處理IO 的能力
select 幾乎所有的操作系統平臺都支持,poll是對select的升級
epoll,Linux系統內核2.5+開始支持,對select和poll的增強,在監視的基礎上,增加了回調機制,BSD,Mac平臺有kqueque,windows有iocp
select 為例,將關註的IO 操作 告訴select函數 並調用,進程阻塞,內核監視select關註的文件描述符fd,被關註的任何一個fd對應的IO準備好了數據,select 返回,在使用read將數據復制到用戶進程。
一般情況下,select最多能監聽1024個fd(可以修改,不建議修改),但是由於select 采用輪詢的方式,當管理的IO 多了,每次都要遍歷全部額fd,效率低下(每次某個IO 設備準備好了,都需要遍歷一遍select)
基於事件驅動的epoll沒有管理的fd的上限, 且是回調機制,不需要遍歷,效率很高。
事件驅動IO:
通知機制:
1、水平觸發通知,一直通知,直到處理
2、邊緣觸發, 只通知一次
event 是事件驅動IO
異步IO:
進程發起異步IO 請求,立即返回,內核完成 IO 的兩個階段,內核給進程發一個信號
7、Python中 IO 多路 復用
IO 多路復用:
-
- 大多數操作系統都支持select 和poll
- Linux 2.5+ 支持epoll
- BSD,Mac 支持kqueque
- windoes的iocp
Python的select庫
實現了select , poll 系統調用,這個基本上操作系統都支持,部分實現了epoll
底層的IO 多路復用模塊。
開發中的選擇:
1、完全誇平臺,使用select ,poll,但是性能較差
2、針對不同操作系統自行選擇支持的技術,
select 維護一個文件描述符數據結構,單個進程使用有上限,通常1024,線性掃描這個數據結構,效率低,
poll和select的區別是內部數據結構使用鏈表,沒有這個最大限制,但是依然是線性遍歷才能知道那個設備就緒了
epoll使用事件通知機制,使用回調機制提高效率
select poll 還要從內核空間復制消息到用戶空間,而epoll通過內核空間 和用戶空間共享的一塊內存來減少復制(mmap))
Python-異步編程