欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python協(xié)程方式的實(shí)現(xiàn)及意義筆記分享

 更新時(shí)間:2021年09月14日 08:55:54   作者:季布,  
協(xié)程也被稱為微線程,是一種用戶態(tài)的上下文切換技術(shù),簡而言之,就是通過一個(gè)線程實(shí)現(xiàn)代碼互相切換執(zhí)行,本文主要給大家介紹實(shí)現(xiàn)協(xié)程的幾種方法

協(xié)程

協(xié)程不是計(jì)算機(jī)提供的,是程序員認(rèn)為創(chuàng)造
協(xié)程也被稱為微線程,是一種用戶態(tài)的上下文切換技術(shù),簡而言之,就是通過一個(gè)線程實(shí)現(xiàn)代碼互相切換執(zhí)行
實(shí)現(xiàn)協(xié)程的幾種方法:

  • 1)greenlet,早期模塊
  • 2)yield關(guān)鍵字
  • 3)asyncio裝飾器 (python3.4以后引入的)
  • 4)async,await關(guān)鍵字 (python3.5) 推薦

1.greenlet實(shí)現(xiàn)協(xié)程

greentlet是一個(gè)第三方模塊,需要提前安裝 pip3 install greenlet才能使用。

from greenlet import greenlet
def func1():
    print(1)        # 第1步:輸出 1
    gr2.switch()    # 第3步:切換到 func2 函數(shù)
    print(2)        # 第6步:輸出 2
    gr2.switch()    # 第7步:切換到 func2 函數(shù),從上一次執(zhí)行的位置繼續(xù)向后執(zhí)行
def func2():
    print(3)        # 第4步:輸出 3
    gr1.switch()    # 第5步:切換到 func1 函數(shù),從上一次執(zhí)行的位置繼續(xù)向后執(zhí)行
    print(4)        # 第8步:輸出 4
gr1 = greenlet(func1)
gr2 = greenlet(func2)
gr1.switch() # 第1步:去執(zhí)行 func1 函數(shù)

輸出的結(jié)果:
1
3
2
4

注意:switch中也可以傳遞參數(shù)用于在切換執(zhí)行時(shí)相互傳遞值。

2.yield

基于Python的生成器的yield和yield form關(guān)鍵字實(shí)現(xiàn)協(xié)程代碼。

def func1():
    yield 1   #第一步執(zhí)行這里會生成1
    yield from func2() #這里會跳到func2,然后執(zhí)行里面的代碼,執(zhí)行完func2函數(shù)后會繼續(xù)以跳轉(zhuǎn)之前的狀態(tài)繼續(xù)執(zhí)行以下代碼
    yield 2
def func2():
    yield 3
    yield 4    
# 這里是一個(gè)生成器對象
f1 = func1()
# 遍歷執(zhí)行生成器
for item in f1:
    print(item)

執(zhí)行結(jié)果
1
3
4
2

注:用這種方法比較牽強(qiáng),真正開發(fā)環(huán)境中基本不會用這種方法實(shí)現(xiàn)協(xié)程(yield form關(guān)鍵字是在Python3.3中引入的。)

3.asyncio

在Python3.4之前官方未提供協(xié)程的類庫,一般大家都是使用greenlet等其他來實(shí)現(xiàn)。在Python3.4發(fā)布后官方正式支持協(xié)程,即:asyncio模塊。

import asyncio
#這就是一個(gè)用協(xié)程實(shí)現(xiàn)的函數(shù)
@asyncio.coroutine
def func1():
    print(1)
    yield from asyncio.sleep(2)  # 遇到IO耗時(shí)操作,自動(dòng)化切換到tasks中的其他任務(wù)
    print(2)
loop = asyncio.get_event_loop()
#執(zhí)行
loop.run_until_complete(func1())

同時(shí)執(zhí)行多個(gè)協(xié)程

import asyncio
@asyncio.coroutine
def func1():
    print(1)
    yield from asyncio.sleep(2)  # 遇到IO耗時(shí)操作,自動(dòng)化切換到tasks中的其他任務(wù)
    print(2)
@asyncio.coroutine
def func2():
    print(3)
    yield from asyncio.sleep(2) # 遇到IO耗時(shí)操作,自動(dòng)化切換到tasks中的其他任務(wù)
    print(4)
tasks = [
    asyncio.ensure_future( func1() ),
    asyncio.ensure_future( func2() )
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

結(jié)果
1
3
2
4

注意:基于asyncio模塊實(shí)現(xiàn)的協(xié)程比之前的要更厲害,因?yàn)樗膬?nèi)部還集成了遇到IO耗時(shí)操作自動(dòng)切花的功能。

4.async & awit

async & awit 關(guān)鍵字在Python3.5版本中正式引入,基于他編寫的協(xié)程代碼其實(shí)就是 上一示例 的加強(qiáng)版,讓代碼可以更加簡便。

Python3.8之后 @asyncio.coroutine 裝飾器就會被移除,推薦使用async & awit 關(guān)鍵字實(shí)現(xiàn)協(xié)程代碼。

import asyncio
async def func1():
    print(1)
    await asyncio.sleep(2)
    print(2)
async def func2():
    print(3)
    await asyncio.sleep(2)
    print(4)
tasks = [
    asyncio.ensure_future(func1()),
    asyncio.ensure_future(func2())
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

常用的是:greenlet,async&awit

協(xié)程的意義

在一個(gè)線程中遇到IO耗時(shí),線程不會等待,利用空余的時(shí)間去執(zhí)行其他的方法

爬蟲案例

例如:用代碼實(shí)現(xiàn)下載 url_list 中的圖片。

方式一:同步編程實(shí)現(xiàn)

import requests
def download_image(url):
    print("開始下載:",url)
    # 發(fā)送網(wǎng)絡(luò)請求,下載圖片
    response = requests.get(url)
    print("下載完成")
    # 圖片保存到本地文件
    file_name = url.rsplit('_')[-1]
    with open(file_name, mode='wb') as file_object:
        file_object.write(response.content)
if __name__ == '__main__':
    url_list = [
        'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg',
        'https://www2.autoimg.cn/newsdfs/g30/M01/3C/E2/120x90_0_autohomecar__ChcCSV2BBICAUntfAADjJFd6800429.jpg',
        'https://www3.autoimg.cn/newsdfs/g26/M0B/3C/65/120x90_0_autohomecar__ChcCP12BFCmAIO83AAGq7vK0sGY193.jpg'
    ]
    for item in url_list:
        download_image(item)

結(jié)果
開始下載: https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg
下載完成
開始下載: https://www2.autoimg.cn/newsdfs/g30/M01/3C/E2/120x90_0_autohomecar__ChcCSV2BBICAUntfAADjJFd6800429.jpg
下載完成
開始下載: https://www3.autoimg.cn/newsdfs/g26/M0B/3C/65/120x90_0_autohomecar__ChcCP12BFCmAIO83AAGq7vK0sGY193.jpg
下載完成

方式二:基于協(xié)程的異步編程實(shí)現(xiàn)

import aiohttp
import asyncio
async def fetch(session, url):
    print("發(fā)送請求:", url)
    async with session.get(url, verify_ssl=False) as response:
        content = await response.content.read()
        file_name = url.rsplit('_')[-1]
        with open(file_name, mode='wb') as file_object:
            file_object.write(content)
async def main():
    async with aiohttp.ClientSession() as session:
        url_list = [
            'https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg',
            'https://www2.autoimg.cn/newsdfs/g30/M01/3C/E2/120x90_0_autohomecar__ChcCSV2BBICAUntfAADjJFd6800429.jpg',
            'https://www3.autoimg.cn/newsdfs/g26/M0B/3C/65/120x90_0_autohomecar__ChcCP12BFCmAIO83AAGq7vK0sGY193.jpg'
        ]
        tasks = [asyncio.create_task(fetch(session, url)) for url in url_list]
        await asyncio.wait(tasks)
if __name__ == '__main__':
    asyncio.run(main())

結(jié)果
發(fā)送請求: https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg
發(fā)送請求: https://www2.autoimg.cn/newsdfs/g30/M01/3C/E2/120x90_0_autohomecar__ChcCSV2BBICAUntfAADjJFd6800429.jpg
發(fā)送請求: https://www3.autoimg.cn/newsdfs/g26/M0B/3C/65/120x90_0_autohomecar__ChcCP12BFCmAIO83AAGq7vK0sGY193.jpg
下載完成 https://www2.autoimg.cn/newsdfs/g30/M01/3C/E2/120x90_0_autohomecar__ChcCSV2BBICAUntfAADjJFd6800429.jpg
下載完成 https://www3.autoimg.cn/newsdfs/g26/M0B/3C/65/120x90_0_autohomecar__ChcCP12BFCmAIO83AAGq7vK0sGY193.jpg
下載完成 https://www3.autoimg.cn/newsdfs/g26/M02/35/A9/120x90_0_autohomecar__ChsEe12AXQ6AOOH_AAFocMs8nzU621.jpg

上述兩種的執(zhí)行對比之后會發(fā)現(xiàn),基于協(xié)程的異步編程 要比 同步編程的效率高了很多。因?yàn)椋?/p>

  • 同步編程,按照順序逐一排隊(duì)執(zhí)行,如果圖片下載時(shí)間為2分鐘,那么全部執(zhí)行完則需要6分鐘。
  • 異步編程,幾乎同時(shí)發(fā)出了3個(gè)下載任務(wù)的請求(遇到IO請求自動(dòng)切換去發(fā)送其他任務(wù)請求),如果圖片下載時(shí)間為2分鐘,那么全部執(zhí)行完畢也大概需要2分鐘左右就可以了。

小結(jié)

協(xié)程一般應(yīng)用在有IO操作的程序中,因?yàn)閰f(xié)程可以利用IO等待的時(shí)間去執(zhí)行一些其他的代碼,從而提升代碼執(zhí)行效率。

以上就是Python協(xié)程的方式實(shí)現(xiàn)及意義筆記分享的詳細(xì)內(nèi)容,更多關(guān)于Python協(xié)程的方式實(shí)現(xiàn)及意義的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Linux下將Python的Django項(xiàng)目部署到Apache服務(wù)器

    Linux下將Python的Django項(xiàng)目部署到Apache服務(wù)器

    這篇文章主要介紹了Python的Django項(xiàng)目部署到Apache服務(wù)器上的要點(diǎn)總結(jié),文中針對的是wsgi連接方式,需要的朋友可以參考下
    2015-12-12
  • SymPy庫關(guān)于矩陣的基本操作和運(yùn)算

    SymPy庫關(guān)于矩陣的基本操作和運(yùn)算

    本文主要介紹了SymPy庫關(guān)于矩陣的基本操作和運(yùn)算,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Django入門使用示例

    Django入門使用示例

    這篇文章主要介紹了Django入門使用示例,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Python字符串hashlib加密模塊使用案例

    Python字符串hashlib加密模塊使用案例

    這篇文章主要介紹了Python字符串hashlib加密模塊使用案例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Pytorch中的廣播機(jī)制詳解(Broadcast)

    Pytorch中的廣播機(jī)制詳解(Broadcast)

    這篇文章主要介紹了Pytorch中的廣播機(jī)制詳解(Broadcast),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 對python中類的繼承與方法重寫介紹

    對python中類的繼承與方法重寫介紹

    今天小編就為大家分享一篇對python中類的繼承與方法重寫介紹,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Pandas庫中ffill函數(shù)的具體使用

    Pandas庫中ffill函數(shù)的具體使用

    ffill(forward fill)是Pandas庫中DataFrame和Series對象的一個(gè)函數(shù),用于填充缺失值,本文主要介紹了Pandas庫中ffill函數(shù)的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • 基于python list對象中嵌套元組使用sort時(shí)的排序方法

    基于python list對象中嵌套元組使用sort時(shí)的排序方法

    下面小編就為大家分享一篇基于python list對象中嵌套元組使用sort時(shí)的排序方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • python pytest進(jìn)階之xunit fixture詳解

    python pytest進(jìn)階之xunit fixture詳解

    這篇文章主要介紹了python pytest進(jìn)階之xunit fixture詳解,了解unittest的同學(xué)應(yīng)該知道我們在初始化環(huán)境和銷毀工作時(shí),unittest使用的是setUp,tearDown方法,那么在pytest框架中同樣存在類似的方法,今天我們就來具體說明,需要的朋友可以參考下
    2019-06-06
  • 教你利用Python玩轉(zhuǎn)histogram直方圖的五種方法

    教你利用Python玩轉(zhuǎn)histogram直方圖的五種方法

    這篇文章主要給大家介紹了關(guān)于如何利用Python玩轉(zhuǎn)histogram直方圖的五種方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-07-07

最新評論