摘要:具有以下基本同步原語子進程提供了通過創建和管理子進程的。雖然隊列不是線程安全的,但它們被設計為專門用于代碼。表示異步操作的最終結果。
Python的asyncio是使用 async/await 語法編寫并發代碼的標準庫。通過上一節的講解,我們了解了它不斷變化的發展歷史。到了Python最新穩定版 3.7 這個版本,asyncio又做了比較大的調整,把這個庫的API分為了 高層級API和低層級API,并引入asyncio.run()這樣的高級方法,讓編寫異步程序更加簡潔。
本節希望提綱挈領地介紹最新 3.7 版的asnycio,先從全局認識Python這個異步IO庫。
asyncio的高層級API主要提高如下幾個方面:
并發地運行Python協程并完全控制其執行過程;
執行網絡IO和IPC;
控制子進程;
通過隊列實現分布式任務;
同步并發代碼。
asyncio的低層級API用以支持開發異步庫和框架:
創建和管理事件循環(event loop),提供異步的API用于網絡,運行子進程,處理操作系統信號等;
通過transports實現高效率協議;
通過async/await 語法橋架基于回調的庫和代碼。
asyncio高級API高層級API讓我們更方便的編寫基于asyncio的應用程序。這些API包括:
(1)協程和任務協程通過 async/await 語法進行聲明,是編寫異步應用的推薦方式。歷史的?@asyncio.coroutine?和?yield from?已經被棄用,并計劃在Python 3.10中移除。協程可以通過?asyncio.run(coro, *, debug=False)?函數運行,該函數負責管理事件循環并完結異步生成器。它應該被用作asyncio程序的主入口點,相當于main函數,應該只被調用一次。
任務被用于并發調度協程,可用于網絡爬蟲的并發。使用?asyncio.create_task()?就可以把一個協程打包為一個任務,該協程會自動安排為很快運行。
協程,任務和Future都是可等待對象。其中,Future是低層級的可等待對象,表示一個異步操作的最終結果。
(2)流流是用于網絡連接的高層級的使用 async/await的原語。流允許在不使用回調或低層級協議和傳輸的情況下發送和接收數據。異步讀寫TCP有客戶端函數?asyncio.open_connection()?和 服務端函數?asyncio.start_server()?。它還支持 Unix Sockets:?asyncio.open_unix_connection()?和?asyncio.start_unix_server()。
(3)同步原語asyncio同步原語的設計類似于threading模塊的原語,有兩個重要的注意事項:
asyncio原語不是線程安全的,因此它們不應該用于OS線程同步(而是用threading)
這些同步原語的方法不接受超時參數; 使用asyncio.wait_for()函數執行超時操作。
asyncio具有以下基本同步原語:
Lock
Event
Condition
Semaphore
BoundedSemaphore
(4)子進程asyncio提供了通過 async/await 創建和管理子進程的API。不同于Python標準庫的subprocess,asyncio的子進程函數都是異步的,并且提供了多種工具來處理這些函數,這就很容易并行執行和監視多個子進程。創建子進程的方法主要有兩個:
coroutine asyncio.create_subprocess_exec()
coroutine asyncio.create_subprocess_shell()
asyncio 隊列的設計類似于標準模塊queue的類。雖然asyncio隊列不是線程安全的,但它們被設計為專門用于 async/await 代碼。需要注意的是,asyncio隊列的方法沒有超時參數,使用?asyncio.wait_for()函數進行超時的隊列操作。
因為和標注模塊queue的類設計相似,使用起來跟queue無太多差異,只需要在對應的函數前面加 await 即可。asyncio 隊列提供了三種不同的隊列:
class asyncio.Queue 先進先出隊列
class asyncio.PriorityQueue 優先隊列
class asyncio.LifoQueue 后進先出隊列
(6)異常asyncio提供了幾種異常,它們是:
TimeoutError,
CancelledError,
InvalidStateError,
SendfileNotAvailableError
IncompleteReadError
LimitOverrunError
asyncio低級API低層級API為編寫基于asyncio的庫和框架提供支持,有意編寫異步庫和框架的大牛們需要熟悉這些低層級API。主要包括:
(1)事件循環事件循環是每個asyncio應用程序的核心。 事件循環運行異步任務和回調,執行網絡IO操作以及運行子進程。
應用程序開發人員通常應該使用高級asyncio函數,例如asyncio.run(),并且很少需要引用循環對象或調用其方法。
Python 3.7 新增了?asyncio.get_running_loop()函數。
(2)FuturesFuture對象用于將基于低層級回調的代碼與高層級的 async/await 代碼進行橋接。
Future表示異步操作的最終結果。 不是線程安全的。
Future是一個可等待對象。 協程可以等待Future對象,直到它們有結果或異常集,或者直到它們被取消。
通常,Futures用于啟用基于低層級回調的代碼(例如,在使用asyncio傳輸實現的協議中)以與高層級 async/await 代碼進行互操作。
Transport 和 Protocol由低層級事件循環使用,比如函數loop.create_connection()。它們使用基于回調的編程風格,并支持網絡或IPC協議(如HTTP)的高性能實現。
在最高級別,傳輸涉及字節的傳輸方式,而協議確定要傳輸哪些字節(在某種程度上何時傳輸)。
換種方式說就是:傳輸是套接字(或類似的I/O端點)的抽象,而協議是從傳輸的角度來看的應用程序的抽象。
另一種觀點是傳輸和協議接口共同定義了一個使用網絡I/O和進程間I/O的抽象接口。
傳輸和協議對象之間始終存在1:1的關系:協議調用傳輸方法來發送數據,而傳輸調用協議方法來傳遞已接收的數據。
大多數面向連接的事件循環方法(例如loop.create_connection())通常接受protocol_factory參數,該參數用于為接受的連接創建Protocol對象,由Transport對象表示。 這些方法通常返回(傳輸,協議)元組。
(4)策略(Policy)事件循環策略是一個全局的按進程劃分的對象,用于控制事件循環的管理。 每個事件循環都有一個默認策略,可以使用策略API對其進行更改和自定義。
策略定義了上下文的概念,并根據上下文管理多帶帶的事件循環。 默認策略將上下文定義為當前線程。
通過使用自定義事件循環策略,可以自定義get_event_loop(),set_event_loop()和new_event_loop()函數的行為。
(5)平臺支持asyncio模塊設計為可移植的,但由于平臺的底層架構和功能,某些平臺存在細微的差異和限制。在Windows平臺,有些是不支持的,比如?loop.create_unix_connection()?and?loop.create_unix_server()。而Linux和比較新的macOS全部支持。
總結Python 3.7 通過對asyncio分組使得它的架構更加清晰,普通寫異步IO的應用程序只需熟悉高層級API,需要寫異步IO的庫和框架時才需要理解低層級的API。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43852.html
摘要:并發的方式有多種,多線程,多進程,異步等。多線程和多進程之間的場景切換和通訊代價很高,不適合密集型的場景關于多線程和多進程的特點已經超出本文討論的范疇,有興趣的同學可以自行搜索深入理解。 編程中,我們經常會遇到并發這個概念,目的是讓軟件能充分利用硬件資源,提高性能。并發的方式有多種,多線程,多進程,異步IO等。多線程和多進程更多應用于CPU密集型的場景,比如科學計算的時間都耗費在CPU...
摘要:創建第一個協程推薦使用語法來聲明協程,來編寫異步應用程序。協程兩個緊密相關的概念是協程函數通過定義的函數協程對象調用協程函數返回的對象。它是一個低層級的可等待對象,表示一個異步操作的最終結果。 我們講以Python 3.7 上的asyncio為例講解如何使用Python的異步IO。 showImg(https://segmentfault.com/img/remote/14600000...
摘要:快速開始在安裝之前在支持異步的過程中,都經歷了哪些比較重大的更新。踏出第一步我們將正式使用來構建一個項目,讓我們踏出第一步,利用來編寫一個返回字符串的服務程序。本次示例的源代碼全部在上,見。 快速開始 在安裝Sanic之前,讓我們一起來看看Python在支持異步的過程中,都經歷了哪些比較重大的更新。 首先是Python3.4版本引入了asyncio,這讓Python有了支持異步IO的標...
摘要:的異步代碼分析是的一個框架,基于,所以叫。不可避免的,可讀性會比較差。想找教程的話,請移步官方教程,寫得還是挺不錯的。建議不要直接使用,而只把它當成的一個樣例。 Python 的異步 IO:Aiohttp Client 代碼分析 Aiohttp 是 Python 的一個 HTTP 框架,基于 asyncio,所以叫 Aiohttp。 我主要是看源碼,想理解它的設計,所以附上了類圖與時序...
閱讀 2458·2021-09-27 13:36
閱讀 2163·2019-08-29 18:47
閱讀 2129·2019-08-29 15:21
閱讀 1394·2019-08-29 11:14
閱讀 1979·2019-08-28 18:29
閱讀 1622·2019-08-28 18:04
閱讀 568·2019-08-26 13:58
閱讀 3206·2019-08-26 12:12