您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關python中單線程和異步協(xié)程工作方式的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
在python3.4之后新增了asyncio模塊,可以幫我們檢測IO(只能是網絡IO【HTTP連接就是網絡IO操作】),實現(xiàn)應用程序級別的切換(異步IO)。注意:asyncio只能發(fā)tcp級別的請求,不能發(fā)http協(xié)議。
異步IO:所謂「異步 IO」,就是你發(fā)起一個 網絡IO 操作,卻不用等它結束,你可以繼續(xù)做其他事情,當它結束時,你會得到通知。
實現(xiàn)方式:單線程+協(xié)程實現(xiàn)異步IO操作。
異步協(xié)程用法
接下來讓我們來了解下協(xié)程的實現(xiàn),從 Python 3.4 開始,Python 中加入了協(xié)程的概念,但這個版本的協(xié)程還是以生成器對象為基礎的,在 Python 3.5 則增加了 async/await,使得協(xié)程的實現(xiàn)更加方便。首先我們需要了解下面幾個概念:
event_loop:事件循環(huán),相當于一個無限循環(huán),我們可以把一些函數(shù)注冊到這個事件循環(huán)上,當滿足條件發(fā)生的時候,就會調用對應的處理方法。
coroutine:中文翻譯叫協(xié)程,在 Python 中常指代為協(xié)程對象類型,我們可以將協(xié)程對象注冊到時間循環(huán)中,它會被事件循環(huán)調用。我們可以使用 async 關鍵字來定義一個方法,這個方法在調用時不會立即被執(zhí)行,而是返回一個協(xié)程對象。
task:任務,它是對協(xié)程對象的進一步封裝,包含了任務的各個狀態(tài)。
future:代表將來執(zhí)行或沒有執(zhí)行的任務的結果,實際上和 task 沒有本質區(qū)別。
另外我們還需要了解 async/await 關鍵字,它是從 Python 3.5 才出現(xiàn)的,專門用于定義協(xié)程。其中,async 定義一個協(xié)程,await 用來掛起阻塞方法的執(zhí)行。
1.定義一個協(xié)程
示例:
from time import sleep import asyncio async def request(url): print('正在請求url') sleep(2) print('下載成功') # 返回一個特殊的協(xié)程對象,request函數(shù)內部不會被執(zhí)行 c = request('www.baidu.com') # 實例化一個事件循環(huán)對象 loop = asyncio.get_event_loop() # 基于事件循環(huán)對象創(chuàng)建一個任務對象,并將協(xié)程對象封裝到該對象中 task = loop.create_task(c) # 另一種形式實例化任務對象的方法 task = asyncio.ensure_future(c) # 將協(xié)程對象注冊到事件循環(huán)對象中,并需要啟動事件循環(huán)對象 # 當事件循環(huán)對象內的第一個參數(shù)遇到阻塞是,就會自動執(zhí)行后面的對象,當?shù)谝粋€對象的阻塞結束是會上報給事件循環(huán)對象,然后事件循環(huán)對象繼續(xù)執(zhí)行第一個對象,從而達到異步的效果 loop.run_until_complete(task)
2.給任務對象綁定回調
import asyncio async def request(url): print('正在請求url') print('下載成功') return url # 回調函數(shù)必須有一個參數(shù):task【任務對象】 # task.result():任務對象中封裝的協(xié)程對象對應的特殊函數(shù)內部的返回值 def callback(task): print('this is callback') print(task.result()) c = request('www.baidu.com') # 創(chuàng)建一個任務對象 task = asyncio.ensure_future(c) # 給任務對象綁定一個回調函數(shù) task.add_done_callback(callback) # 實例化一個事件循環(huán)對象 loop = asyncio.get_event_loop() # 將協(xié)程對象注冊到事件循環(huán)對象中,并需要啟動事件循環(huán)對象 loop.run_until_complete(task)
3.多任務異步協(xié)程
import asyncio import time urls = ['www.baidu.com','www.sogou,com','www.goubanjia.com'] start_time = time.time() async def request(url): print('正在請求url') # 在多任務異步協(xié)程事項中,不可以出現(xiàn)不支持異步的相關代碼,sleep不支持 # sleep(2) await asyncio.sleep(2) print('下載成功') loop = asyncio.get_event_loop() # 任務列表:防止多個任務對象 tasks = [] for url in urls: c = request(url) task = asyncio.ensure_future(c) tasks.append(task) loop.run_until_complete(asyncio.wait(tasks)) print(time.time() - start_time)
4.多異步任務協(xié)程應用
# aiohttp:支持異步的一個基于網絡請求的模塊 import aiohttp import asyncio import time urls = ['http://127.0.0.1:5000/jay', 'http://127.0.0.1:5000/bobo', 'http://127.0.0.1:5000/tom',] start_time = time.time() async def get_pageText(url): async with aiohttp.ClientSession() as s:# 實例化請求對象 async with await s.get(url) as response: page_text = await response.text() print(page_text) # 這里有返回值,是因為要用回調函數(shù)進行數(shù)據解析 return page_text # 封裝回調函數(shù)用于數(shù)據解析 def parse(task): # 1.獲取相應數(shù)據 page_text = task.reault() print(page_text+',即將進行數(shù)據解析...') # 以下解析操作 tasks = [] for url in urls: c = get_pageText(url) task = asyncio.ensure_future(c) # 給任務對象綁定回調函數(shù)用于數(shù)據解析 task.add_done_callback(parse) tasks.append(task) loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks)) print(time.time() - start_time)
關于“python中單線程和異步協(xié)程工作方式的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。