国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python中的并發處理之asyncio包使用的詳解

2020-02-22 23:34:58
字體:
來源:轉載
供稿:網友

導語:本文章記錄了本人在學習Python基礎之控制流程篇的重點知識及個人心得,打算入門Python的朋友們可以來一起學習并交流。

本文重點:

1、了解asyncio包的功能和使用方法;
2、了解如何避免阻塞型調用;
3、學會使用協程避免回調地獄。

一、使用asyncio包做并發編程

1、并發與并行

并發:一次處理多件事。
并行:一次做多件事。
并發用于制定方案,用來解決可能(但未必)并行的問題。并發更好。

2、asyncio概述

了解asyncio的4個特點:

    asyncio包使用事件循環驅動的協程實現并發。 適合asyncio API的協程在定義體中必須使用yield from,而不能使用yield。 使用asyncio處理的協程,需在定義體上使用@asyncio.coroutine裝飾。裝飾的功能在于凸顯協程,同時當協程不產出值,協程會被垃圾回收。 Python3.4起,asyncio包只直接支持TCP和UDP協議。如果想使用asyncio實現HTTP客戶端和服務器時,常使用aiohttp包。

在協程中使用yield from需要注意兩點:

    使用yield froml鏈接的多個協程最終必須由不是協程的調用方驅動,調用方顯式或隱式在最外層委派生成器上調用next()函數或 .send()方法。 鏈條中最內層的子生成器必須是簡單的生成器(只使用yield)或可迭代的對象。

但在asyncio包的API中使用yield from還需注意兩個細節:

    asyncio包中編寫的協程鏈條始終通過把最外層委派生成器傳給asyncio包API中的某個函數驅動,例如loop.run_until_complete()。即不通過調用next()函數或 .send()方法驅動協程。 編寫的協程鏈條最終通過yield from把職責委托給asyncio包中的某個協程函數或協程方法。即最內層的子生成器是庫中真正執行I/O操作的函數,而不是我們自己編寫的函數。

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

import asyncioimport itertoolsimport sys@asyncio.coroutine # 交給 asyncio 處理的協程要使用 @asyncio.coroutine 裝飾def spin(msg):  for char in itertools.cycle('|/-//'):    status = char + ' ' + msg    print(status)    try:      yield from asyncio.sleep(.1) # 使用 yield from asyncio.sleep(.1) 代替 time.sleep(.1),這樣的休眠不會阻塞事件循環。    except asyncio.CancelledError: # 如果 spin 函數蘇醒后拋出 asyncio.CancelledError 異常,其原因是發出了取消請求,因此退出循環。      break@asyncio.coroutinedef slow_function(): # slow_function 函數是協程,在用休眠假裝進行 I/O 操作時,使用 yield from 繼續執行事件循環。  # 假裝等待I/O一段時間  yield from asyncio.sleep(3) # yield from asyncio.sleep(3) 表達式把控制權交給主循環,在休眠結束后恢復這個協程。  return 42@asyncio.coroutinedef supervisor(): # supervisor 函數也是協程  spinner = asyncio.async(spin('thinking!')) # asyncio.async(...) 函數排定 spin 協程的運行時間,使用一個 Task 對象包裝spin 協程,并立即返回。  print('spinner object:', spinner)  result = yield from slow_function() # 驅動 slow_function() 函數。結束后,獲取返回值。# 同時,事件循環繼續運行,因為slow_function 函數最后使用 yield from asyncio.sleep(3) 表達式把控制權交回給了主循環。  spinner.cancel() # Task 對象可以取消;取消后會在協程當前暫停的 yield 處拋出 asyncio.CancelledError 異常。協程可以捕獲這個異常,也可以延遲取消,甚至拒絕取消。  return resultif __name__ == '__main__':  loop = asyncio.get_event_loop() # 獲取事件循環的引用  result = loop.run_until_complete(supervisor()) # 驅動 supervisor 協程,讓它運行完畢;這個協程的返回值是這次調用的返回值。  loop.close()  print('Answer:', result)            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 夹江县| 临清市| 腾冲县| 磐石市| 简阳市| 信丰县| 莱西市| 林甸县| 开远市| 盐山县| 封开县| 玉门市| 巴彦县| 湘潭市| 墨竹工卡县| 连山| 麻阳| 错那县| 罗甸县| 六安市| 佳木斯市| 黑龙江省| 深水埗区| 五华县| 福州市| 高平市| 尼勒克县| 东山县| 永川市| 闽清县| 云龙县| 信丰县| 汉源县| 安国市| 中山市| 湘潭市| 彭泽县| 舒兰市| 邢台市| 普洱| 临湘市|