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

Python中asyncio的多種用法舉例(異步同步)

 更新時間:2024年11月13日 09:47:49   作者:碼農葫蘆俠  
這篇文章主要給大家介紹了關于Python中asyncio的多種用法,包括順序執(zhí)行非異步任務、順序執(zhí)行異步任務、并行執(zhí)行異步任務以及并行執(zhí)行非異步任務,通過使用asyncio模塊,可以有效地提高程序的執(zhí)行效率,尤其是在處理I/O密集型任務時,需要的朋友可以參考下

1 引言 

Python 的 asyncio 模塊為異步編程提供了強大的支持,但在某些場景下,我們可能需要處理異步任務與非異步(同步)任務的順序執(zhí)行或并行執(zhí)行。本篇文章將逐步帶你了解如何在 Python 中處理這些不同類型的任務。

2 順序執(zhí)行非異步任務 

在日常編程中,最常見的情況之一就是順序執(zhí)行一系列非異步(同步)的任務。這些任務在同一個線程中執(zhí)行,通常會阻塞主程序的運行,直到任務完成。

示例代碼:

import time

def blocking_task(id):
    print(f"Blocking task {id} started")
    time.sleep(2)  # 模擬一個阻塞操作
    print(f"Blocking task {id} finished")

# 順序執(zhí)行多個同步任務
def main():
    for i in range(3):
        blocking_task(i)

main()

解釋:

在此代碼中,每個任務按順序執(zhí)行,time.sleep() 會阻塞當前線程,直到所有任務結束。這種順序執(zhí)行的方式雖然簡單直接,但效率較低,尤其當任務涉及 I/O 操作時,會浪費大量時間。

3 順序執(zhí)行異步任務

如果我們希望提高任務的執(zhí)行效率,可以考慮使用異步任務。異步任務不會阻塞主線程,而是會等待特定的事件(例如 I/O 操作的完成),然后繼續(xù)執(zhí)行。

示例代碼:

import asyncio

async def async_task(id):
    print(f"Async task {id} started")
    await asyncio.sleep(2)  # 模擬異步操作
    print(f"Async task {id} finished")

# 順序執(zhí)行多個異步任務
async def main():
    for i in range(3):
        await async_task(i)

asyncio.run(main())

解釋:

通過使用 async def 定義異步函數,await 關鍵字用于暫停任務的執(zhí)行并等待異步操作完成。雖然這些任務是異步的,但由于我們使用了 await,它們仍然是順序執(zhí)行的。

3 并行執(zhí)行異步任務

在某些情況下,我們可能希望異步任務能夠并行執(zhí)行,而不是一個接一個地等待。此時可以使用 asyncio.gather(),它允許我們并行運行多個異步任務,從而提高程序效率。

示意圖:

示例代碼:

import asyncio

async def async_task(id):
    print(f"Async task {id} started")
    await asyncio.sleep(2)
    print(f"Async task {id} finished")

# 并行執(zhí)行多個異步任務
async def main():
    tasks = [async_task(i) for i in range(3)]
    await asyncio.gather(*tasks)

asyncio.run(main())

解釋:

asyncio.gather() 會并行執(zhí)行多個異步任務,而不是按順序等待。任務在后臺同時運行,極大提高了效率,尤其是當任務需要等待 I/O 時(例如網絡請求、文件操作等)。

? 注意:

tasks = [async_task(i) for i in range(3)] 這個時候不會執(zhí)行async_task函數,只是創(chuàng)建協(xié)程對象,還沒真正的啟動。

  • 當你調用 async_task(i) 時,它不會立即執(zhí)行,而是返回一個 協(xié)程對象(coroutine object),這個對象代表一個等待執(zhí)行的異步任務。
  • 只有當你 await 這個協(xié)程對象或者將它傳遞給 asyncio.gather()、asyncio.create_task()、asyncio.run() 等函數時,協(xié)程才會開始執(zhí)行。

4 并行執(zhí)行非異步任務(阻塞任務)

如果你有一些外部庫提供的阻塞任務(如文件讀寫、網絡操作等),這些任務無法直接變?yōu)楫惒胶瘮怠榱伺c異步任務并行執(zhí)行這些阻塞任務,asyncio.run_in_executor() 是你的好幫手。

示意圖:

示例代碼:使用線程池并行執(zhí)行同步任務

import asyncio
import time
from concurrent.futures import ThreadPoolExecutor

def blocking_task(id):
    print(f"Blocking task {id} started")
    time.sleep(2)
    print(f"Blocking task {id} finished")

async def main():
    with ThreadPoolExecutor() as pool:
        tasks = [
            asyncio.get_event_loop().run_in_executor(pool, blocking_task, i)
            for i in range(3)
        ]
        await asyncio.gather(*tasks)

asyncio.run(main())

解釋:

run_in_executor() 將阻塞的任務交給線程池(或進程池)執(zhí)行,而不會阻塞主事件循環(huán)。這使得我們可以同時處理異步任務和阻塞任務。

使用進程池還是線程池?

  • 線程池(ThreadPoolExecutor):適用于 I/O 密集型任務,如文件操作或網絡請求。這類任務通常會等待外部事件完成,因此不需要消耗大量 CPU 資源。
  • 進程池(ProcessPoolExecutor):適合 CPU 密集型任務,如數據處理和計算。使用進程池可以充分利用多核 CPU,提升性能。

示例代碼:使用進程池

from concurrent.futures import ProcessPoolExecutor
import asyncio

def cpu_intensive_task(id):
    print(f"CPU task {id} started")
    result = sum(i*i for i in range(10**6))  # 模擬CPU密集任務
    print(f"CPU task {id} finished with result: {result}")

async def main():
    with ProcessPoolExecutor() as pool:
        tasks = [
            asyncio.get_event_loop().run_in_executor(pool, cpu_intensive_task, i)
            for i in range(3)
        ]
        await asyncio.gather(*tasks)

asyncio.run(main())

5 總結

  • 順序執(zhí)行非異步任務:通常用于簡單的任務,但效率低下,容易阻塞線程。
  • 順序執(zhí)行異步任務:使用 asyncio 提供的異步函數,能夠在等待 I/O 時不阻塞主線程。
  • 并行執(zhí)行異步任務:通過 asyncio.gather(),可以輕松并行多個異步任務,極大提高執(zhí)行效率。
  • 并行執(zhí)行非異步任務:通過 run_in_executor() 將阻塞任務交給線程池或進程池,保證異步任務和同步任務可以并行執(zhí)行。
  • 線程池 vs 進程池:選擇線程池處理 I/O 密集型任務,進程池處理 CPU 密集型任務。

通過這些技巧,你可以在 Python 中輕松管理各種類型的任務,實現高效并行處理。

到此這篇關于Python中asyncio的多種用法的文章就介紹到這了,更多相關Python中asyncio多種用法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Python函數中的可變長參數詳解

    Python函數中的可變長參數詳解

    在本篇文章里小編給大家整理的是關于Python函數中的可變長參數的相關知識點內容,有需要的朋友們參考下。
    2019-09-09
  • python數據可視化之條形圖畫法

    python數據可視化之條形圖畫法

    這篇文章主要為大家詳細介紹了python數據可視化之條形圖畫法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Python利器openpyxl之操作excel表格

    Python利器openpyxl之操作excel表格

    這篇文章主要給大家介紹了關于Python利器openpyxl之操作excel表格的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • python爬蟲之利用Selenium+Requests爬取拉勾網

    python爬蟲之利用Selenium+Requests爬取拉勾網

    這篇文章主要介紹了python爬蟲之利用Selenium+Requests爬取拉勾網,文中有非常詳細的代碼示例,對正在學習python爬蟲的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-04-04
  • python編寫分類決策樹的代碼

    python編寫分類決策樹的代碼

    這篇文章主要為大家詳細介紹了python編寫分類決策樹的代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • python:pandas合并csv文件的方法(圖書數據集成)

    python:pandas合并csv文件的方法(圖書數據集成)

    下面小編就為大家分享一篇python:pandas合并csv文件的方法(圖書數據集成),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Scrapy啟動報錯invalid syntax的解決

    Scrapy啟動報錯invalid syntax的解決

    這篇文章主要介紹了Scrapy啟動報錯invalid syntax的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Python使用Crypto庫實現加密解密的示例詳解

    Python使用Crypto庫實現加密解密的示例詳解

    這篇文章主要為大家詳細介紹了Python如何使用Crypto庫實現加密解密的功能,文中的示例代碼講解詳細,對我們學習Python有一定的幫助,需要的可以參考一下
    2023-01-01
  • django執(zhí)行原生SQL查詢的實現

    django執(zhí)行原生SQL查詢的實現

    本文主要介紹了django執(zhí)行原生SQL查詢的實現,主要有兩種方法實現,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • python數據歸一化及三種方法詳解

    python數據歸一化及三種方法詳解

    這篇文章主要介紹了python數據歸一化及三種方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08

最新評論