在Python同步方法中調(diào)用異步方法不阻塞主流程的幾種方案
如果你想在 同步方法 中調(diào)用 異步方法 save_category_icon
,并且不阻塞主線程,可以使用 asyncio.create_task()
或 threading
/concurrent.futures
來(lái)實(shí)現(xiàn)。
方案 1:使用 asyncio.create_task()(推薦)
如果你的代碼 運(yùn)行在事件循環(huán)中(如 Flask + Quart 或 FastAPI),可以使用:
import asyncio async def save_category_icon(category_id=0, category_name=None): await asyncio.sleep(2) # 模擬異步任務(wù) print(f"Icon saved for category {category_id} - {category_name}") def edit_category(): loop = asyncio.get_event_loop() loop.create_task(save_category_icon(category_id=1, category_name="Test")) print("Main process continues...") # 不會(huì)等待異步任務(wù)完成 edit_category()
? 優(yōu)點(diǎn):
- 不會(huì)阻塞主線程
- 任務(wù)會(huì)在后臺(tái)執(zhí)行
- 適用于已運(yùn)行的
asyncio
事件循環(huán)(FastAPI、Quart 等)
方案 2:使用 threading(適用于 Flask 同步環(huán)境)
如果你的代碼在 Flask(同步框架)中運(yùn)行,推薦用 threading
運(yùn)行異步方法:
import threading import asyncio def run_async_task(): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop.run_until_complete(save_category_icon(category_id=1, category_name="Test")) def edit_category(): threading.Thread(target=run_async_task, daemon=True).start() print("Main process continues...") # 不會(huì)等待異步任務(wù)完成 edit_category()
? 優(yōu)點(diǎn):
- 不會(huì)阻塞 Flask 主進(jìn)程
- 在 Flask 等同步環(huán)境下仍可運(yùn)行異步任務(wù)
daemon=True
確保進(jìn)程退出時(shí)線程自動(dòng)關(guān)閉
方案 3:使用 concurrent.futures(適用于高并發(fā)情況)
如果你的異步任務(wù)是 CPU 密集型 或者需要更好的線程池管理,可以使用 concurrent.futures
:
import asyncio from concurrent.futures import ThreadPoolExecutor executor = ThreadPoolExecutor() def run_async_task(): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) loop.run_until_complete(save_category_icon(category_id=1, category_name="Test")) def edit_category(): executor.submit(run_async_task) # 提交任務(wù)到線程池 print("Main process continues...") edit_category()
? 優(yōu)點(diǎn):
- 適用于高并發(fā)任務(wù)
- 可以復(fù)用 ThreadPoolExecutor,提高性能
- 不阻塞主進(jìn)程
選哪個(gè)方案?
方案 | 適用場(chǎng)景 | 優(yōu)點(diǎn) |
---|---|---|
asyncio.create_task() | 代碼已經(jīng)運(yùn)行在事件循環(huán)(FastAPI、Quart) | 輕量級(jí),非阻塞 |
threading.Thread() | Flask 或 Django(同步框架) | 適用于 Flask,后臺(tái)執(zhí)行任務(wù) |
concurrent.futures.ThreadPoolExecutor | 高并發(fā)或多個(gè)異步任務(wù) | 適用于 CPU 密集型任務(wù) |
推薦最佳方案
- FastAPI、Quart: ? 使用
asyncio.create_task()
- Flask、Django(同步): ? 使用
threading.Thread()
- 高并發(fā)任務(wù): ? 使用
concurrent.futures.ThreadPoolExecutor
這樣 異步任務(wù)會(huì)在后臺(tái)運(yùn)行,不會(huì)阻塞主流程!
總結(jié)
到此這篇關(guān)于在Python同步方法中調(diào)用異步方法不阻塞主流程的幾種方案的文章就介紹到這了,更多相關(guān)Python同步方法調(diào)用異步方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python編程學(xué)習(xí)之如何判斷3個(gè)數(shù)的大小
這篇文章主要給大家介紹了關(guān)于Python編程學(xué)習(xí)之如何判斷3個(gè)數(shù)的大小的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08詳解Python中命令行參數(shù)argparse的常用命令
這篇文章主要為大家詳細(xì)介紹了Python中命令行參數(shù)argparse的一些常用命令,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的可以了解一下2023-01-01Python文件打開(kāi)方式實(shí)例詳解【a、a+、r+、w+區(qū)別】
這篇文章主要介紹了Python文件打開(kāi)方式,結(jié)合實(shí)例形式詳細(xì)分析了Python文件打開(kāi)函數(shù)的使用及a、a+、r+、w+等屬性功能、使用區(qū)別與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-03-03Python中的圖形繪制簡(jiǎn)單動(dòng)畫(huà)實(shí)操
這篇文章主要介紹了Python中的圖形繪制簡(jiǎn)單動(dòng)畫(huà)實(shí)操,?Matplotlib?是一個(gè)非常廣泛的庫(kù),它也支持圖形動(dòng)畫(huà),動(dòng)畫(huà)工具以?matplotlib.animation?基類(lèi)為中心,它提供了一個(gè)框架,圍繞該框架構(gòu)建動(dòng)畫(huà),下面來(lái)看看具體的實(shí)現(xiàn)過(guò)程吧,需要的小伙伴可以參考一下2022-02-02Python虛擬環(huán)境庫(kù)virtualenvwrapper安裝及使用
這篇文章主要介紹了Python虛擬環(huán)境庫(kù)virtualenvwrapper安裝及使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06Python和Java的語(yǔ)法對(duì)比分析語(yǔ)法簡(jiǎn)潔上python的確完美勝出
Python是一種廣泛使用的解釋型、高級(jí)編程、通用型編程語(yǔ)言,由吉多·范羅蘇姆創(chuàng)造,第一版發(fā)布于1991年。這篇文章主要介紹了Python和Java的語(yǔ)法對(duì)比,語(yǔ)法簡(jiǎn)潔上python的確完美勝出 ,需要的朋友可以參考下2019-05-05基于tensorflow指定GPU運(yùn)行及GPU資源分配的幾種方式小結(jié)
今天小編就為大家分享一篇基于tensorflow指定GPU運(yùn)行及GPU資源分配的幾種方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02