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

Python異步編程中asyncio.gather的并發(fā)控制詳解

 更新時間:2025年03月24日 15:49:02   作者:傻啦嘿喲  
在Python異步編程生態(tài)中,asyncio.gather是并發(fā)任務(wù)調(diào)度的核心工具,本文將通過實際場景和代碼示例,展示如何結(jié)合信號量機制實現(xiàn)精準(zhǔn)并發(fā)控制,希望對大家有所幫助

在Python異步編程生態(tài)中,asyncio.gather是并發(fā)任務(wù)調(diào)度的核心工具。然而當(dāng)面對海量任務(wù)時,不加控制的并發(fā)可能引發(fā)資源耗盡、服務(wù)降級等問題。本文將通過實際場景和代碼示例,展示如何結(jié)合信號量機制實現(xiàn)精準(zhǔn)并發(fā)控制,既保證吞吐量又避免系統(tǒng)過載。

一、asyncio.gather的原始行為解析

asyncio.gather的設(shè)計初衷是批量執(zhí)行異步任務(wù),其默認行為類似于"全速沖刺":

import asyncio
 
async def task(n):
    print(f"Task {n} started")
    await asyncio.sleep(1)
    print(f"Task {n} completed")
    return n
 
async def main():
    tasks = [task(i) for i in range(10)]
    results = await asyncio.gather(*tasks)
    print(f"Total results: {len(results)}")
 
asyncio.run(main())

在這個示例中,10個任務(wù)會立即全部啟動,1秒后幾乎同時完成。這種"全并發(fā)"模式在以下場景存在隱患:

網(wǎng)絡(luò)請求:同時發(fā)起數(shù)千個HTTP請求可能被目標(biāo)服務(wù)器封禁

文件IO:磁盤IO密集型操作會拖慢系統(tǒng)響應(yīng)

數(shù)據(jù)庫連接:超過連接池限制導(dǎo)致報錯

二、信號量控制法:給并發(fā)裝上"節(jié)流閥"

asyncio.Semaphore通過限制同時執(zhí)行的任務(wù)數(shù),實現(xiàn)精準(zhǔn)并發(fā)控制。其核心機制是:

初始化時設(shè)定最大并發(fā)數(shù)(如10)

每個任務(wù)執(zhí)行前必須獲取信號量

任務(wù)完成后釋放信號量

async def controlled_task(sem, n):
    async with sem:  # 獲取信號量
        print(f"Task {n} acquired semaphore")
        await asyncio.sleep(1)
        print(f"Task {n} released semaphore")
        return n
 
async def main():
    sem = asyncio.Semaphore(3)  # 最大并發(fā)3
    tasks = [controlled_task(sem, i) for i in range(10)]
    results = await asyncio.gather(*tasks)
    print(f"Total results: {len(results)}")
 
asyncio.run(main())

執(zhí)行效果:

始終只有3個任務(wù)在執(zhí)行
每完成1個任務(wù),立即啟動新任務(wù)
總耗時≈4秒(10/3向上取整)

三、進階控制策略

3.1 動態(tài)調(diào)整并發(fā)數(shù)

通過監(jiān)控隊列長度動態(tài)調(diào)整信號量:

async def dynamic_control():
    sem = asyncio.Semaphore(5)
    task_queue = asyncio.Queue()
    
    # 生產(chǎn)者
    async def producer():
        for i in range(20):
            await task_queue.put(i)
    
    # 消費者
    async def consumer():
        while True:
            item = await task_queue.get()
            async with sem:
                print(f"Processing {item}")
                await asyncio.sleep(1)
            task_queue.task_done()
    
    # 動態(tài)調(diào)整
    def monitor(queue):
        while True:
            size = queue.qsize()
            if size > 10:
                sem._value = max(1, sem._value - 1)
            elif size < 5:
                sem._value = min(10, sem._value + 1)
            asyncio.sleep(1)
    
    await asyncio.gather(
        producer(),
        *[consumer() for _ in range(3)],
        asyncio.to_thread(monitor, task_queue)
    )
 
asyncio.run(dynamic_control())

3.2 分批執(zhí)行策略

對于超大規(guī)模任務(wù)集,可采用分批處理:

def chunked(iterable, chunk_size):
    for i in range(0, len(iterable), chunk_size):
        yield iterable[i:i+chunk_size]
 
async def batch_processing():
    all_tasks = [task(i) for i in range(100)]
    
    for batch in chunked(all_tasks, 10):
        print(f"Processing batch: {len(batch)} tasks")
        await asyncio.gather(*batch)
 
asyncio.run(batch_processing())

優(yōu)勢:

  • 避免內(nèi)存爆炸
  • 方便進度跟蹤
  • 支持中間狀態(tài)保存

四、性能對比與最佳實踐

控制方式吞吐量資源占用實現(xiàn)復(fù)雜度適用場景
無控制小型任務(wù)集
固定信號量通用場景
動態(tài)信號量中高中低需要彈性控制的場景
分批處理超大規(guī)模任務(wù)集

最佳實踐建議:

網(wǎng)絡(luò)請求類任務(wù):并發(fā)數(shù)控制在5-20之間

文件IO操作:并發(fā)數(shù)不超過CPU邏輯核心數(shù)*2

數(shù)據(jù)庫操作:遵循連接池最大連接數(shù)限制

始終設(shè)置合理的超時時間:

try:
    await asyncio.wait_for(task(), timeout=10)
except asyncio.TimeoutError:
    print("Task timed out")

五、常見錯誤與解決方案

錯誤1:信號量未正確釋放

# 錯誤示例:缺少async with
sem = asyncio.Semaphore(3)
sem.acquire()
await task()
sem.release()  # 容易忘記釋放

解決方案:

# 正確用法
async with sem:
    await task()  # 自動獲取和釋放

錯誤2:任務(wù)異常導(dǎo)致信號量泄漏

async def risky_task():
    async with sem:
        raise Exception("Oops!")  # 異常導(dǎo)致sem未釋放

解決方案:

async def safe_task():
    sem_acquired = False
    try:
        async with sem:
            sem_acquired = True
            # 執(zhí)行可能出錯的操作
    finally:
        if not sem_acquired:
            sem.release()

結(jié)語

asyncio.gather配合信號量機制,就像給異步程序裝上了智能節(jié)流閥。通過合理設(shè)置并發(fā)參數(shù),既能讓程序高效運行,又能避免系統(tǒng)過載。實際開發(fā)中應(yīng)根據(jù)任務(wù)類型、資源限制和SLA要求,選擇最合適的并發(fā)控制策略。記住:優(yōu)秀的并發(fā)控制不是追求最大速度,而是找到性能與穩(wěn)定性的最佳平衡點。

到此這篇關(guān)于Python異步編程中asyncio.gather的并發(fā)控制詳解的文章就介紹到這了,更多相關(guān)Python asyncio.gather內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Python去除字符串中某個字符的多種實現(xiàn)方式比較

    使用Python去除字符串中某個字符的多種實現(xiàn)方式比較

    python中字符串是不可變的,所以無法直接刪除字符串之間的特定字符,下面這篇文章主要給大家介紹了關(guān)于使用Python去除字符串中某個字符的多種實現(xiàn)方式比較的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • 利用PyTorch實現(xiàn)爬山算法

    利用PyTorch實現(xiàn)爬山算法

    這篇文章主要介紹了利用PyTorch實現(xiàn)爬山算法,爬山算法是一種局部擇優(yōu)的方法,采用啟發(fā)式方法,是對深度優(yōu)先搜索的一種改進,它利用反饋信息幫助生成解的決策,屬于人工智能算法的一種
    2022-07-07
  • 用?Python?繪制全國鴻星爾克門店分布圖

    用?Python?繪制全國鴻星爾克門店分布圖

    這篇文章主要介紹了用?Python?繪制全國鴻星爾克門店分布圖,今天就以某度地圖?用Python爬蟲看一下全國到底有多少家鴻星爾克門店,,需要的朋友可以參考一下
    2022-01-01
  • Python實現(xiàn)快速提取PDF文檔中的圖片

    Python實現(xiàn)快速提取PDF文檔中的圖片

    提取PDF文檔中的圖片是一項常見的任務(wù),本文將介紹如何使用PyPDF2和pdfminer.six這兩個庫來提取PDF文檔中的圖片,感興趣的可以了解一下
    2023-06-06
  • python GUI庫圖形界面開發(fā)之PyQt5信號與槽基礎(chǔ)使用方法與實例

    python GUI庫圖形界面開發(fā)之PyQt5信號與槽基礎(chǔ)使用方法與實例

    這篇文章主要介紹了python GUI庫圖形界面開發(fā)之PyQt5信號與槽基礎(chǔ)使用方法與實例,需要的朋友可以參考下
    2020-03-03
  • 在Python中繪制帶有連接線的雙餅圖(操作代碼)

    在Python中繪制帶有連接線的雙餅圖(操作代碼)

    這篇文章主要介紹了如何在Python中繪制帶有連接線的雙餅圖,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • python使用參數(shù)對嵌套字典進行取值的方法

    python使用參數(shù)對嵌套字典進行取值的方法

    這篇文章主要介紹了python使用參數(shù)對嵌套字典進行取值,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • 基于Python制作天眼查小程序的示例代碼

    基于Python制作天眼查小程序的示例代碼

    本文主要介紹了如何利用Python制作一個天眼查GUI程序。這次的GUI程序,我們使用的框架是PyQt5,該框架擁有比tkinter更為豐富的內(nèi)置組件,在界面美化方面,貌似也更勝一籌,快跟隨小編一起學(xué)起來吧
    2022-09-09
  • 深入淺析Python 中的sklearn模型選擇

    深入淺析Python 中的sklearn模型選擇

    這篇文章主要介紹了Python sklearn模型選擇的相關(guān)知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • Python爬蟲庫urllib的使用教程詳解

    Python爬蟲庫urllib的使用教程詳解

    Python?給人的印象是抓取網(wǎng)頁非常方便,提供這種生產(chǎn)力的,主要依靠的就是?urllib、requests這兩個模塊。本文主要給大家介紹一下urllib的使用,感興趣的可以了解一下
    2022-11-11

最新評論