當前位置:編程學習大全網 - 源碼下載 - 如何使用Python並發處理asyncio包

如何使用Python並發處理asyncio包

這次給大家帶來的是如何使用Python並發處理asyncio包,Python並發處理asyncio包有哪些註意事項。下面是壹個實際案例,我們來看看。

導語:本文記錄了我學習Python基本控制流的關鍵知識和個人經驗,有意入門Python的朋友可以前來壹起學習交流。

這篇文章的重點是:

1,了解asyncio包的功能和用法;

2.了解如何避免阻塞呼叫;

3、學會利用過程,避免喚回地獄。

首先,使用asyncio包進行並發編程。

1,並發和並行

並發性:同時處理多件事情。

並行:同時做很多事情。

並發用於制定計劃和解決可能(但不壹定)的並行問題。並發更好。

2.asyncio概述

了解asyncio的四個特征:

Asyncio包使用事件周期驅動的協程實現並發。

適用於asyncio API的流程必須在定義體中使用yield from,而不是yield。

asyncio處理的流程需要在定義體上用@asyncio.coroutine修飾。裝修的作用是突出協同,當協同沒有產生價值時,協同就會被垃圾回收。

從Python3.4開始,asyncio包只直接支持TCP和UDP協議。如果要用asyncio實現HTTP客戶端和服務器,經常會用到aiople()。也就是說,協程不是通過調用next()函數或。send()方法。

書面協同鏈最終通過yield from將責任委托給asyncio包中的協同功能或方法。也就是最裏面的子生成器是實際在庫中執行I/O操作的函數,而不是我們自己寫的函數。

例——通過asyncio包和協程以動畫形式顯示文本旋轉指針;

進口異步

導入itertools

導入系統

@asyncio.coroutine #交給asyncio的談判過程要用@asyncio.coroutine來修飾。

定義旋轉(消息):

對於itertools.cycle中的char(' |/-\ '):

狀態=字符+ ' ' +消息

打印(狀態)

嘗試:

asyncio的產量。sleep (.1) #使用asyncio的產量。sleep (.1)而不是time.sleep(.1),這樣不會阻塞事件循環。

除了阿辛西奧。CancelledError: #如果spin函數喚醒並拋出壹個asyncio。cancelederror異常,原因是發出了取消請求,所以退出循環。

破裂

@asyncio.coroutine

def slow _ function():# slow _ function函數是壹個協程。假裝在休眠狀態下執行I/O操作時,使用yield from繼續執行事件循環。

#假裝等待I/O壹會兒

表達式yield from asyncio。睡眠(3) #從焦慮中屈服。sleep (3)將控制權交給主循環,並在休眠後繼續這個過程。

返回42

@asyncio.coroutine

Def supervisor(): # supervisor函數也是壹個協程。

spinner = async io . async(spin(' thinking!'))# asyncio.async(...)函數調度自旋協程的運行時間,用任務對象包裝自旋協程,並立即返回。

打印(' spinner對象:',spinner)

result = yield from slow_function()#驅動slow _ function()函數。完成後,獲取返回值。

#同時,事件循環繼續運行,因為slow_function函數最終使用表達式yield from asyncio.sleep(3)將控制返回到主循環。

可以取消spinner.cancel() #任務對象;取消後,asyncio。CancelledError異常將在進程當前掛起的yield處引發。流程可以捕捉這個異常,延遲取消,甚至拒絕取消。

回送結果

if name == 'main ':

Loop = asyncio.get_event_loop() #獲取事件循環的引用。

結果=循環。run _ until _ complete(supervisor())#驅動管理器完成運行;這個過程的返回值就是這個調用的返回值。

loop.close()

打印('答案:',結果)3。線程和協程的比較。

線程:調度程序可以在任何時候中斷線程。妳必須記得鎖好。保護程序的重要部分,防止多步操作在執行過程中被中斷,防止數據處於無效狀態。

協調:默認情況下,它將被完全保護,以防止中斷。沒有必要為協程保持鎖定。如果在多個線程之間同步操作,協程本身也會同步,因為任何時候只有壹個協程運行。

4、從周期、任務和進度上輸出。

在asyncio程序包中,期間和流程密切相關,因為您可以使用yield from從asyncio生成結果。未來對象。這意味著如果foo是壹個並發函數或者是壹個返回Future或Task實例的普通函數,可以寫成如下形式:res=yield from foo()。這也是asyncio包裏很多地方可以交換合同和條款的原因之壹。

第二,避免阻止通話

1,有兩種方法可以避免阻塞調用來停止整個應用程序進程:

在單獨的線程中運行每個阻塞操作。

將每個阻塞操作轉換成壹個非阻塞異步調用。

使用多線程處理大量連接會消耗太多內存,所以通常使用回調來實現異步調用。

2.使用Executor對象防止阻塞事件循環:

使用loop.run_in_executor將阻塞的作業(如保存文件)委托給線程池。

@asyncio.coroutine

def download_one(cc,base_url,信號量,verbose):

嘗試:

用(信號量的產量):

image = get _ flag(base _ URL,cc)的yield

除了web。HTTPNotFound:

status = HTTPStatus.not_found

消息= '未找到'

例外情況除外:

從exc中取出FetchError(cc)

否則:

Loop = asyncio.get_event_loop() #獲取事件循環對象的引用。

Loop.run _ in _ executor (none,# none使用TrreadPoolExecutor的默認實例。

Save _ flag,image,cc.lower ()+'。gif') #傳入壹個可調用對象。

status = HTTPStatus.ok

msg = 'OK '

如果詳細和消息:

打印(抄送,郵件)

ThreadPoolExecutor對象在返回結果(status,cc)asyncio的事件循環之後維護。我們可以調用run_in_executor方法,將可調用對象發送給它執行。

第三,從回調到到期和協商

回調地獄:如果壹個操作需要依賴之前操作的結果,它必須嵌套回調。

Python中的回調地獄:

定義階段1(響應1):

請求2 =步驟1(響應1)

api_call2(請求2,階段2)

定義階段2(響應2):

請求3 =步驟2(響應2)

api_call3(請求3,階段3)

定義階段3(響應3):

步驟3(響應3)

API _ Call1(請求1,步驟1)使用協程和yield from結構進行異步編程,無需回調:

@asyncio.coroutine

定義三個階段(請求1):

response1 =來自api_call1()的產量

請求2 =步驟1(響應1)

response2 =來自api_call2(請求2)的產量

請求3 =步驟2(響應2)

response3 =來自api_call3(請求3)的產量

步驟3(響應3)

loop.create_task(三個階段(請求1))

#協程不能直接調用,指定協程的執行時間必須按事件周期顯示,也可以在其他有調度執行時間的協程中使用yield from expression激活。

使用asyncio包可以實現TCP和HTTP服務器。

Web服務將成為asyncio包的壹個重要使用場景。

相信看完這個案例,妳已經掌握了方法。更多精彩請關註Gxl上其他相關文章!

推薦閱讀:

如何將python字符串轉換成二維數組

如何用Vue導出excel表格函數

  • 上一篇:Pid內核源代碼
  • 下一篇:《俠盜飛車:聖安地列斯》遊戲秘籍大全誰有?
  • copyright 2024編程學習大全網