python 單執行緒和非同步協程工作方式解析

2022-10-04 16:06:29 字數 3260 閱讀 5255

在python3.4之後新增了asyncio模組,可以幫我們檢測io(只能是網路io【http連線就是網路io操作】),實現應用程式級別的切換(非同步io)。注意:asyncio只能發tcp級別的請求,不能發http協議。

非同步io:所謂「非同步 io」,就是你發起乙個 網路io 操作,卻不用等它結束,你可以繼續做其他事情,當它結束時,你會得到通知。

實現方式:單執行緒+協程實現非同步io操作。

非同步協程用法

接下來讓我們來了解下協程的實現,從 python 3.4 開始,python 中加入了協程的概念,但這個版本的協程還是以生成器物件為基礎的,在 python 3.5 則增加了 async/await,使得協程的實現更加方便。首先我們需要了解下面幾個概念:

另外我們還需要了解 async/await 關鍵字,它是從 python 3.5 才出現的,專門用於定義協程。其中,async 定義乙個協程,await 用來掛起阻塞方法的執行。

1.定義乙個協程

示例:from time import sleep

import asyncio

async def request(url):

print('正在請求url')

sleep(2)

print('**成功')

# 返zmwoje回乙個特殊的協程物件,request函式內部不會被執行

# 例項化乙個事件迴圈物件

loop = asyncio.get_event_loop()

# 基於事件迴圈物件建立乙個任務物件,並將協程物件封裝到該物件中

task = loop.create_task(c)

# 另一種形式例項化任務物件的方法

task = asyncio.ensure_future(c)

# 將協程物件註冊到事件迴圈物件中,並需要啟動事件迴圈物件

# 當事件迴圈物件內的第乙個引數遇到阻塞是,就會自動執行後面的物件,當第乙個物件的阻塞結束是會上報給事件迴圈物件,然後事件迴圈物件繼續執行第乙個物件,從而達到非同步的效果

loop.run_until_complete(task)

2.給任務物件繫結回程式設計客棧調

import asyncio

async def request(url):

print('正在請求url')

print('**成功')

return url

# **函式必須有乙個引數:task【任務物件】

# task.result():任務物件zmwoje中封裝的協程物件對應的特殊函式內部的返回值

def callback(task):

print('this is callback')

print(task.result())

# 建立乙個任務物件

task = asyncio.ensure_future(c)

# 給任務物件繫結乙個**函式

task.add_done_callback(callback)

# 例項化乙個事件迴圈物件程式設計客棧

loop = asyncio.get_event_loop()

# 將協程物件註冊到事件迴圈物件中,並需要啟動事件迴圈物件

loop.run_until_complete(task)

3.多工非同步協程

print('正在請求url')

# 在多工非同步協程事項中,不可以出現不支援非同步的相關**,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.多非同步任務協程應用

# aiohttp:支援非同步的乙個基於網路請求的模組

async with aiohttp.clientsession() as s:# 例項化請求物件

async with await s.get(url) as response:

page_text = await response.text()

print(page_text)

# 這裡有返回值,是因為要用**函式進行資料解析

return page_text

# 封裝**函式用於資料解析

def parse(task):

# 1.獲取相應資料

page_text = task.reault()

print(page_text+',即將進行資料解析...')

# 以下解析操作

tasks =

for url in urls:

c = get_pagetext(url)

task = asyncio.ensure_future(c)

# 給任務物件繫結**函式用於資料解析

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 單執行緒和非同步協程工作方式解析

本文位址:

爬蟲 單執行緒 多工非同步協程

要點 1.resquests模組不支援非同步,在需要非同步的地方使用aiohttp模組進行替換 2.定義乙個協程函式,建立協程任務,將 協程 打包為乙個 task 排入日程準備執行。返回task物件 獲取當前事件迴圈,開啟迴圈 data await response.read 此處參考aiohttp...

爬蟲 單執行緒 多工非同步協程

任務物件 事件迴圈 aiohttp 支援非同步網路請求的模組 伺服器端 from flask import flask import time def index bobo time.sleep 2 return hello index1 def index jay time.sleep 2 ret...

單執行緒 非同步協程的簡單爬蟲模型

event loop 事件迴圈,相當於乙個無限迴圈 不清楚迴圈多少次 我們可以把一些特殊函式註冊 放置 到這個事件迴圈上,當滿足某些條件的時候,函式就會被迴圈執行。程式是按照設定的順序從頭執行到尾,執行的次數也是完全按照設定。當在編寫非同步程式時,必然其中有部分程式的執行耗時是比較久的,需要先讓出當...