电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

python中asyncio異步編程學習

瀏覽:8日期:2022-06-23 11:40:17
1.   想學asyncio,得先了解協程

攜程的意義:

計算型的操作,利用協程來回切換執行,沒有任何意義,來回切換并保存狀態 反倒會降低性能。 IO型的操作,利用協程在IO等待時間就去切換執行其他任務,當IO操作結束后再自動回調,那么就會大大節省資源并提供性能,從而實現異步編程(不等待任務結束就可以去執行其他代碼2.協程和多線程之間的共同點和區別:

共同點:

都是并發操作,多線程同一時間點只能有一個線程在執行,協程同一時間點只能有一個任務在執行;

不同點:

多線程,是在I/O阻塞時通過切換線程來達到并發的效果,在什么情況下做線程切換是由操作系統來決定的,開發者不用操心,但會造成競爭條件 (race condition) ;

協程,只有一個線程,在I/O阻塞時通過在線程內切換任務來達到并發的效果,在什么情況下做任務切換是開發者決定的,不會有競爭條件 (race condition) 的情況;多線程的線程切換比協程的任務切換開銷更大;對于開發者而言,多線程并發的代碼比協程并發的更容易書寫。

一般情況下協程并發的處理效率比多線程并發更高。

3. greenlet實現協程

greenlet用于創建協程,switch用于進行協程之間的切換某個協程在執行的過程中可以隨時的被其他協程通過switch函數來打斷,轉而去執行其他協程,當前協程的中斷現場會被保留,一旦中斷的協程再次獲得cpu的執行權首先會恢復現場然后從中斷處繼續執行這種機制下的協程是同步,不能并發

pip install greenlet

import timeimport greenlet def func1(): print('func11') gr2.switch() time.sleep(1) print('func22') gr2.switch() def func2(): print('func33') gr1.switch() time.sleep(1) print('func44') start = time.time()gr1 = greenlet.greenlet(func1)gr2 = greenlet.greenlet(func2)gr1.switch()end = time.time()print(end - start)4. yield關鍵字實現協程

def func1(): yield 1 yield from func2() yield 3 def func2(): yield 2 yield 4 ff = func1()for item in ff: print(item)5.gevent協程(1)gevent實現協程

pip install gevent

from greenlet import greenletfrom time import sleepdef func1(): print('協程1') sleep(2) g2.switch() print('協程1恢復運行') def func2(): print('協程2') sleep(1) g3.switch()def func3(): print('協程3') sleep(1) g1.switch() if __name__ == ’__main__’: # 使用greenlet來創建三個協程 g1 = greenlet(func1) g2 = greenlet(func2) g3 = greenlet(func3) # print(g1) g1.switch() # 讓協程g1取搶占cpu資源(2) gevent實現異步協程

# 協程被創建出來以后默認是多個協程同步執行# 我們可以加入monkey補丁,把同步的協程轉成異步協程from gevent import monkey # 注意:monkey的引入必須在其他模塊之前 monkey.patch_all() # 用monkey給整個協程隊列,添加一個非阻塞I/O的補丁,使得他們成為異步協程import timeimport requestsimport gevent headers = { ’User-Agent’: ’Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36’} def func(url, i): print('協程%d開啟!' % i) res = requests.get(url=url, headers=headers) html = res.text print('協程%d執行結束,獲取到的響應體大小為:%d' % (i, len(html))) if __name__ == ’__main__’: start = time.time() urls = [ 'https://www.baidu.com/', 'https://www.qq.com/', 'https://www.sina.com.cn', 'https://www.ifeng.com/', 'https://www.163.com/' ] # 創建5個協程分別對上面5個網站進行訪問 g_list = [] for i in range(len(urls)): g = gevent.spawn(func, urls[i], i) g_list.append(g) # func(urls[i], i) gevent.joinall(g_list) end = time.time() print(end - start)6. asyncio模塊實現異步協程

在python3.4及之后的版本使用,asyncio厲害之處在于:遇到IO操作時會自動切換執行其它任務

import timeimport asyncio @asyncio.coroutinedef func1(): print(1) yield from asyncio.sleep(1) # 遇到IO耗時操作,自動切換到tasks中的其它任務 print(2) @asyncio.coroutinedef func2(): print(3) yield from asyncio.sleep(1) # 遇到IO耗時操作,自動切換到tasks中的其它任務 print(4) tasks = [ asyncio.ensure_future(func1()), asyncio.ensure_future(func2())] start = time.time()loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.wait(tasks))end = time.time()print(end - start)7. asyc & await關鍵字實現異步編程(現在推薦使用的用法)

在python3.5及之后的版本中可以使用

import timeimport asyncio async def func1(): print(1) await asyncio.sleep(1) print(2) async def func2(): print(3) await asyncio.sleep(1) print(4) tasks = [ asyncio.ensure_future(func1()), asyncio.ensure_future(func2())] start = time.time()loop = asyncio.get_event_loop()loop.run_until_complete(asyncio.wait(tasks))end = time.time()print(end - start)7.1 事件循環

    事件循環,可以把他當做是一個while循環,這個while循環在周期性的運行并執行一些任務,在特定條件下終止循環。

偽代碼:

# 偽代碼任務列表 = [ 任務1, 任務2, 任務3,... ]while True: 可執行的任務列表,已完成的任務列表 = 去任務列表中檢查所有的任務,將’可執行’和’已完成’的任務返回 for 就緒任務 in 已準備就緒的任務列表: 執行已就緒的任務 for 已完成的任務 in 已完成的任務列表: 在任務列表中移除 已完成的任務 如果 任務列表 中的任務都已完成,則終止循環7.2 協程和異步編程

協程函數,定義形式為 async def 的函數。

協程對象,調用 協程函數 所返回的對象。

# 定義一個協程函數async def func(): pass# 調用協程函數,返回一個協程對象result = func()

注意:調用協程函數時,函數內部代碼不會執行,只是會返回一個協程對象。 

7.3 基本應用

程序中,如果想要執行協程函數的內部代碼,需要 事件循環 和 協程對象 配合才能實現,如:

import asyncioasync def func(): print('協程內部代碼')# 調用協程函數,返回一個協程對象。result = func()# 方式一# loop = asyncio.get_event_loop() # 創建一個事件循環# loop.run_until_complete(result) # 將協程當做任務提交到事件循環的任務列表中,協程執行完成之后終止。# 方式二# 本質上方式一是一樣的,內部先 創建事件循環 然后執行 run_until_complete,一個簡便的寫法。# asyncio.run 函數在 Python 3.7 中加入 asyncio 模塊,asyncio.run(result)

這個過程可以簡單理解為:將協程當做任務添加到 事件循環 的任務列表,然后事件循環檢測列表中的協程是否 已準備就緒(默認可理解為就緒狀態),如果準備就緒則執行其內部代碼。

7.4 await關鍵字

await是一個只能在協程函數中使用的關鍵字,用于遇到IO操作時掛起 當前協程(任務),當前協程(任務)掛起過程中 事件循環可以去執行其他的協程(任務),當前協程IO處理完成時,可以再次切換回來執行await之后的代碼,

await + 可等待對象(協程對象、Future對象、Task對象)

示例1:await+協程對象

import asyncio async def func1(): print('start') await asyncio.sleep(1) print('end') return 'func1執行完畢' async def func2(): print('func2開始執行') # await關鍵字后面可以跟可等待對象(協程對象、Future對象、Task對象) response = await func1() print(response) print('func2執行完畢') asyncio.run(func2())

示例2: 協程函數中可以使用多次await關鍵字

import asyncio async def func1(): print('start') await asyncio.sleep(1) print('end') return 'func1執行完畢' async def func2(): print('func2開始執行') # await關鍵字后面可以跟可等待對象(協程對象、Future對象、Task對象) response = await func1() print(response) response2 = await func1() print(response2) print('func2執行完畢') asyncio.run(func2())7.5 task對象

Tasks用于并發調度協程,通過asyncio.create_task(協程對象)的方式創建Task對象,這樣可以讓協程加入事件循環中等待被調度執行。除了使用 asyncio.create_task() 函數以外,還可以用低層級的 loop.create_task() 或 ensure_future() 函數。不建議手動實例化 Task 對象。

本質上是將協程對象封裝成task對象,并將協程立即加入事件循環,同時追蹤協程的狀態。

注意:asyncio.create_task() 函數在 Python 3.7 中被加入。在 Python 3.7 之前,可以改用低層級的 asyncio.ensure_future() 函數。

示例1:

import asyncio async def func(): print(1) await asyncio.sleep(1) print(2) return 'func的返回值' async def main(): print(3) # 創建協程,將協程封裝到一個task對象中并立即添加到事件循環列表中,等待事件循環去執行,(默認是就緒狀態) task1 = asyncio.create_task(func()) # 創建協程,將協程封裝到一個task對象中并立即添加到事件循環列表中,等待事件循環去執行,(默認是就緒狀態) task2 = asyncio.create_task(func()) # 當執行某協程遇到IO操作時,會自動化切換執行其他任務。 # 此處的await是等待相對應的協程全都執行完畢并獲取結果 ret1 = await task1 ret2 = await task2 print(ret1, ret2) asyncio.run(main())

示例2:用的還是比較多的

import asyncio async def func(): print(1) await asyncio.sleep(1) print(2) return 'func的返回值' async def main(): print(3) # 創建協程,將協程封裝到Task對象中并添加到事件循環的任務列表中,等待事件循環去執行(默認是就緒狀態)。 # 在調用 task_list = [ asyncio.create_task(func()), asyncio.create_task(func()) ] # 當執行某協程遇到IO操作時,會自動化切換執行其他任務。 # 此處的await是等待所有協程執行完畢,并將所有協程的返回值保存到done # 如果設置了timeout值,則意味著此處最多等待的秒,完成的協程返回值寫入到done中,未完成則寫到pending中。 done, pending = await asyncio.wait(task_list, timeout=None) print(done) print(pending) asyncio.run(main())

 示例3:

import asyncio async def func(): print('執行協程函數內部代碼') # 遇到IO操作掛起當前協程(任務),等IO操作完成之后再繼續往下執行。當前協程掛起時,事件循環可以去執行其他協程(任務)。 response = await asyncio.sleep(2) print('IO請求結束,結果為:', response) coroutine_list = [func(), func()]# 錯誤:coroutine_list = [ asyncio.create_task(func()), asyncio.create_task(func()) ]# 此處不能直接 asyncio.create_task,因為將Task立即加入到事件循環的任務列表,# 但此時事件循環還未創建,所以會報錯。# 使用asyncio.wait將列表封裝為一個協程,并調用asyncio.run實現執行兩個協程# asyncio.wait內部會對列表中的每個協程執行ensure_future,封裝為Task對象。done, pending = asyncio.run(asyncio.wait(coroutine_list))

總結:

在程序中只要看到async和await關鍵字,其內部就是基于協程實現的異步編程,這種異步編程是通過一個線程在IO等待時間去執行其他任務,從而實現并發。

如果是 I/O 密集型,且 I/O 請求比較耗時的話,使用協程。如果是 I/O 密集型,且 I/O 請求比較快的話,使用多線程。如果是 計算 密集型,考慮可以使用多核 CPU,使用多進程。

以上就是python中asyncio異步編程學習的詳細內容,更多關于python中使用asyncio的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 塑料异型材_PVC异型材_封边条生产厂家_PC灯罩_防撞扶手_医院扶手价格_东莞市怡美塑胶制品有限公司 | 热缩管切管机-超声波切带机-织带切带机-无纺布切布机-深圳市宸兴业科技有限公司 | 艺术生文化课培训|艺术生文化课辅导冲刺-济南启迪学校 | 皮带机_移动皮带机_大倾角皮带机_皮带机厂家 - 新乡市国盛机械设备有限公司 | 铝板冲孔网,不锈钢冲孔网,圆孔冲孔网板,鳄鱼嘴-鱼眼防滑板,盾构走道板-江拓数控冲孔网厂-河北江拓丝网有限公司 | 北京翻译公司_同传翻译_字幕翻译_合同翻译_英语陪同翻译_影视翻译_翻译盖章-译铭信息 | atcc网站,sigma试剂价格,肿瘤细胞现货,人结肠癌细胞株购买-南京科佰生物 | 合肥制氮机_合肥空压机厂家_安徽真空泵-凯圣精机 | 聚合氯化铝_喷雾聚氯化铝_聚合氯化铝铁厂家_郑州亿升化工有限公司 | 假肢-假肢价格-假肢厂家-河南假肢-郑州市力康假肢矫形器有限公司 | 英语词典_成语词典_日语词典_法语词典_在线词典网 | 欧景装饰设计工程有限公司-无锡欧景装饰官网| 网带通过式抛丸机,,网带式打砂机,吊钩式,抛丸机,中山抛丸机生产厂家,江门抛丸机,佛山吊钩式,东莞抛丸机,中山市泰达自动化设备有限公司 | 农业仪器网 - 中国自动化农业仪器信息交流平台 | 防爆暖风机_防爆电暖器_防爆电暖风机_防爆电热油汀_南阳市中通智能科技集团有限公司 | 撕碎机_轮胎破碎机_粉碎机_回收生产线厂家_东莞华达机械有限公司 | 中天寰创-内蒙古钢结构厂家|门式刚架|钢结构桁架|钢结构框架|包头钢结构煤棚 | 热熔胶网膜|pes热熔网膜价格|eva热熔胶膜|热熔胶膜|tpu热熔胶膜厂家-苏州惠洋胶粘制品有限公司 | 广州食堂承包_广州团餐配送_广州堂食餐饮服务公司 - 旺记餐饮 | 注塑模具_塑料模具_塑胶模具_范仕达【官网】_东莞模具设计与制造加工厂家 | 全温恒温摇床-水浴气浴恒温摇床-光照恒温培养摇床-常州金坛精达仪器制造有限公司 | 冷库安装厂家_杭州冷库_保鲜库建设-浙江克冷制冷设备有限公司 | 深圳侦探联系方式_深圳小三调查取证公司_深圳小三分离机构 | 标准件-非标紧固件-不锈钢螺栓-非标不锈钢螺丝-非标螺母厂家-三角牙锁紧自攻-南京宝宇标准件有限公司 | 福建成考网-福建成人高考网 | 干洗加盟网-洗衣店品牌排行-干洗设备价格-干洗连锁加盟指南 | hdpe土工膜-防渗膜-复合土工膜-长丝土工布价格-厂家直销「恒阳新材料」-山东恒阳新材料有限公司 ETFE膜结构_PTFE膜结构_空间钢结构_膜结构_张拉膜_浙江萬豪空间结构集团有限公司 | 沧州友城管业有限公司-内外涂塑钢管-大口径螺旋钢管-涂塑螺旋管-保温钢管生产厂家 | 聚合氯化铝-碱式氯化铝-聚合硫酸铁-聚氯化铝铁生产厂家多少钱一吨-聚丙烯酰胺价格_河南浩博净水材料有限公司 | 塑料瓶罐_食品塑料瓶_保健品塑料瓶_调味品塑料瓶–东莞市富慷塑料制品有限公司 | 深圳昂为官网-气体分析仪,沼气分析仪,动态配气仪,气体传感器厂家 | 胶原检测试剂盒,弹性蛋白检测试剂盒,类克ELISA试剂盒,阿达木单抗ELISA试剂盒-北京群晓科苑生物技术有限公司 | TPE_TPE热塑性弹性体_TPE原料价格_TPE材料厂家-惠州市中塑王塑胶制品公司- 中塑王塑胶制品有限公司 | 注塑机-压铸机-塑料注塑机-卧式注塑机-高速注塑机-单缸注塑机厂家-广东联升精密智能装备科技有限公司 | 北京翻译公司-专业合同翻译-医学标书翻译收费标准-慕迪灵 | 锂电叉车,电动叉车_厂家-山东博峻智能科技有限公司 | 杭州可当科技有限公司—流量卡_随身WiFi_AI摄像头一站式解决方案 | 专业的新乡振动筛厂家-振动筛品质保障-环保振动筛价格—新乡市德科筛分机械有限公司 | 膜结构_ETFE膜结构_膜结构厂家_膜结构设计-深圳市烨兴智能空间技术有限公司 | 全自动面膜机_面膜折叠机价格_面膜灌装机定制_高速折棉机厂家-深圳市益豪科技有限公司 | 异噻唑啉酮-均三嗪-三丹油-1227-中北杀菌剂厂家 |