python 單線程和異步協(xié)程工作方式解析
在python3.4之后新增了asyncio模塊,可以幫我們檢測IO(只能是網(wǎng)絡(luò)IO【HTTP連接就是網(wǎng)絡(luò)IO操作】),實現(xiàn)應(yīng)用程序級別的切換(異步IO)。注意:asyncio只能發(fā)tcp級別的請求,不能發(fā)http協(xié)議。
異步IO:所謂「異步 IO」,就是你發(fā)起一個 網(wǎng)絡(luò)IO 操作,卻不用等它結(jié)束,你可以繼續(xù)做其他事情,當它結(jié)束時,你會得到通知。
實現(xiàn)方式:單線程+協(xié)程實現(xiàn)異步IO操作。
異步協(xié)程用法
接下來讓我們來了解下協(xié)程的實現(xiàn),從 Python 3.4 開始,Python 中加入了協(xié)程的概念,但這個版本的協(xié)程還是以生成器對象為基礎(chǔ)的,在 Python 3.5 則增加了 async/await,使得協(xié)程的實現(xiàn)更加方便。首先我們需要了解下面幾個概念:
- event_loop:事件循環(huán),相當于一個無限循環(huán),我們可以把一些函數(shù)注冊到這個事件循環(huán)上,當滿足條件發(fā)生的時候,就會調(diào)用對應(yīng)的處理方法。
- coroutine:中文翻譯叫協(xié)程,在 Python 中常指代為協(xié)程對象類型,我們可以將協(xié)程對象注冊到時間循環(huán)中,它會被事件循環(huán)調(diào)用。我們可以使用 async 關(guān)鍵字來定義一個方法,這個方法在調(diào)用時不會立即被執(zhí)行,而是返回一個協(xié)程對象。
- task:任務(wù),它是對協(xié)程對象的進一步封裝,包含了任務(wù)的各個狀態(tài)。
- future:代表將來執(zhí)行或沒有執(zhí)行的任務(wù)的結(jié)果,實際上和 task 沒有本質(zhì)區(qū)別。
另外我們還需要了解 async/await 關(guān)鍵字,它是從 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ù)內(nèi)部不會被執(zhí)行
c = request('www.baidu.com')
# 實例化一個事件循環(huán)對象
loop = asyncio.get_event_loop()
# 基于事件循環(huán)對象創(chuàng)建一個任務(wù)對象,并將協(xié)程對象封裝到該對象中
task = loop.create_task(c)
# 另一種形式實例化任務(wù)對象的方法
task = asyncio.ensure_future(c)
# 將協(xié)程對象注冊到事件循環(huán)對象中,并需要啟動事件循環(huán)對象
# 當事件循環(huán)對象內(nèi)的第一個參數(shù)遇到阻塞是,就會自動執(zhí)行后面的對象,當?shù)谝粋€對象的阻塞結(jié)束是會上報給事件循環(huán)對象,然后事件循環(huán)對象繼續(xù)執(zhí)行第一個對象,從而達到異步的效果
loop.run_until_complete(task)
2.給任務(wù)對象綁定回調(diào)
import asyncio
async def request(url):
print('正在請求url')
print('下載成功')
return url
# 回調(diào)函數(shù)必須有一個參數(shù):task【任務(wù)對象】
# task.result():任務(wù)對象中封裝的協(xié)程對象對應(yīng)的特殊函數(shù)內(nèi)部的返回值
def callback(task):
print('this is callback')
print(task.result())
c = request('www.baidu.com')
# 創(chuàng)建一個任務(wù)對象
task = asyncio.ensure_future(c)
# 給任務(wù)對象綁定一個回調(diào)函數(shù)
task.add_done_callback(callback)
# 實例化一個事件循環(huán)對象
loop = asyncio.get_event_loop()
# 將協(xié)程對象注冊到事件循環(huán)對象中,并需要啟動事件循環(huán)對象
loop.run_until_complete(task)
3.多任務(wù)異步協(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')
# 在多任務(wù)異步協(xié)程事項中,不可以出現(xiàn)不支持異步的相關(guān)代碼,sleep不支持
# sleep(2)
await asyncio.sleep(2)
print('下載成功')
loop = asyncio.get_event_loop()
# 任務(wù)列表:防止多個任務(wù)對象
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.多異步任務(wù)協(xié)程應(yīng)用
# aiohttp:支持異步的一個基于網(wǎng)絡(luò)請求的模塊
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)
# 這里有返回值,是因為要用回調(diào)函數(shù)進行數(shù)據(jù)解析
return page_text
# 封裝回調(diào)函數(shù)用于數(shù)據(jù)解析
def parse(task):
# 1.獲取相應(yīng)數(shù)據(jù)
page_text = task.reault()
print(page_text+',即將進行數(shù)據(jù)解析...')
# 以下解析操作
tasks = []
for url in urls:
c = get_pageText(url)
task = asyncio.ensure_future(c)
# 給任務(wù)對象綁定回調(diào)函數(shù)用于數(shù)據(jù)解析
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)
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python之Django自動化資產(chǎn)掃描的實現(xiàn)
這篇文章主要介紹了python之Django自動化資產(chǎn)掃描的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-04-04
關(guān)于Python turtle庫使用時坐標的確定方法
這篇文章主要介紹了關(guān)于Python turtle庫使用時坐標的確定方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03
python爬取NUS-WIDE數(shù)據(jù)庫圖片
本文給大家分享的是使用Python制作爬蟲爬取圖片的小程序,非常的簡單,但是很實用,有需要的小伙伴可以參考下2016-10-10
python?argparse的使用步驟(全網(wǎng)最全)
argparse是python的一個命令行參數(shù)解析包,在代碼需要頻繁修改參數(shù)時,方便使用,主要用法就是在命令行輸入自己想要修改的參數(shù),這篇文章主要介紹了python?argparse的使用步驟(全網(wǎng)最全),需要的朋友可以參考下2023-04-04
利用Python腳本實現(xiàn)ping百度和google的方法
最近在做SEO的時候,為了讓發(fā)的外鏈能夠快速的收錄,想到了利用ping的功能,google和百度都有相關(guān)的ping介紹,有興趣的朋友可以去看看相關(guān)的知識。下面這篇文章主要介紹了利用Python腳本實現(xiàn)ping百度和google的方法,需要的朋友可以參考借鑒,一起來看看吧。2017-01-01
跟老齊學Python之集成開發(fā)環(huán)境(IDE)
IDE的全稱是:Integrated Development Environment,簡稱IDE,也稱為Integration Design Environment、Integration Debugging Environment,翻譯成中文叫做“集成開發(fā)環(huán)境”,在臺灣那邊叫做“整合開發(fā)環(huán)境”。2014-09-09
在spyder IPython console中,運行代碼加入?yún)?shù)的實例
這篇文章主要介紹了在spyder IPython console中,運行代碼加入?yún)?shù)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04

