AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

關于FastAPI中在新線程里調用協成函數問題

來源: 責編: 時間:2024-01-04 09:32:39 314觀看
導讀先前有公眾號朋友問起一個問題,大概的問題是這樣:在異步接口里面接收批量上傳的文件夾后通過webdav3進行批量進行文件處理。其實涉及的問題就是:相對于在異步之中進行線程化的異步處理。大致的代碼如下所示:@uploadrp.pos

先前有公眾號朋友問起一個問題,大概的問題是這樣:xmK28資訊網——每日最新資訊28at.com

在異步接口里面接收批量上傳的文件夾后通過webdav3進行批量進行文件處理。其實涉及的問題就是:相對于在異步之中進行線程化的異步處理。xmK28資訊網——每日最新資訊28at.com

xmK28資訊網——每日最新資訊28at.com

大致的代碼如下所示:xmK28資訊網——每日最新資訊28at.com

@uploadrp.post('/upload/rp')async def upload_rp_file(file: List[UploadFile] = File(...)):   ........    upload_result = await new_upload_file(file_path=file_path, file_name=file_name, old_name=rp_dir_name)       .........

其中對應的new_upload_file也是異步函數,但是里面涉及到webdav3庫的異步的調用,如下代碼所示:xmK28資訊網——每日最新資訊28at.com

async def new_upload_file(file_path, file_name, old_name):    """ 上傳文件夾 """.........  upload_rp_file_result = client.upload_async('' + file_name, file_path,                                                callback=partial(completion_callback, old_file_dir=old_name, file_name=file_name))  .........

容納后在調用upload_async的使用,需要進行任務處理完成的回調,也就是completion_callback函數,它的代碼如下:xmK28資訊網——每日最新資訊28at.com

def completion_callback(old_file_dir, file_name):    pss

它的問題就是在completion_callback還有一個異步的函數需要調用的時候就遇到問題了:xmK28資訊網——每日最新資訊28at.com

(1) 我無法在upload_async上傳文件完成后的回調函數使用async,即 async def completion_callbackxmK28資訊網——每日最新資訊28at.com

(2) 我在completion_callback中獲取當前事件循環,因為執行這個回調函數的時候,控制臺打印當前沒有事件循環xmK28資訊網——每日最新資訊28at.com

3) 我在completion_callback中new一個事件循環(new_event_loop)然后用create_task或run_until_complete執行update_rp_file_status函數的時候,都不成功:xmK28資訊網——每日最新資訊28at.com

  • 要不然就報update_rp_file_status函數跟new的事件循環不是同一個...
  • 要不就是這個update_rp_file_status壓根不執行...
  • 要不就是還沒執行,new出來的事件循環,在update_rp_file_status還沒執行的時候就被銷毀了,很多問題...

問題探究

其實這個問題本質其實就是關于 client.upload_async中啟用了新的線程去異步處理了,導致了開啟了新的線程的問題,如下 client.upload_async的代碼:xmK28資訊網——每日最新資訊28at.com

xmK28資訊網——每日最新資訊28at.com

由此可見,問題肯本原因在于是因為我們是在新線程中調用了異步函數,而新線程沒有自己的事件循環導致的。xmK28資訊網——每日最新資訊28at.com

回到事件循環的本身上,我們知道首先需要知道一點:xmK28資訊網——每日最新資訊28at.com

異步函數需要在事件循環中運行。但是由于我們啟動服務之后,在主線程中,FastAPI應用程序已經創建了一個事件循環,并且通過uvicorn.run()方法來運行該應用程序,而這個的事件循環對象是當前主線程創建出來的, 而當我們在新線程中,也就是client.upload_async調用之后,開啟的線程中并沒有默認的事件循環可用。因此,當你嘗試在新線程中調用異步函數時,就會拋出RuntimeError: There is no current event loop in thread異常,甚至你嘗試打印獲取當前運行的事件循環都無法獲取到。如下代碼所示:xmK28資訊網——每日最新資訊28at.com

from fastapi import FastAPIimport asyncioapp = FastAPI()from threading import Thread  # 創建線程的模塊def task(name):    print(asyncio.get_event_loop())async def do_task():    # 異步任務的邏輯    await asyncio.sleep(1)    print("異步任務完成")@app.get("/items")async def read_item():    p = Thread(target=task, args=('線程1',))    p.start()      return {"data": "ok"}

在上面的等待嗎中我們直接輸出當前 print(asyncio.get_event_loop())也會遇到如下類似的錯誤提示:xmK28資訊網——每日最新資訊28at.com

xmK28資訊網——每日最新資訊28at.com

問題解決

解決此類的問題,開始的時候,因為具體可能沒了解帶業務細節和邏輯,所以給的思路也有點偏差,后來自己嘗試后,其實才發現原來只是一個比較簡單的問題,此類的問題,我們可以在新線程中創建一個新的事件循環,并將任務添加到該事件循環中,以確保異步函數能夠正確運行。這樣,每個線程都有自己的事件循環,可以獨立地運行異步任務。也就是如下的代碼:xmK28資訊網——每日最新資訊28at.com

from fastapi import FastAPIimport asyncioapp = FastAPI()from threading import Thread  # 創建線程的模塊def task(name):    print(asyncio.get_event_loop())    # 嘗試去執行異步任務    asyncio.run(do_task())async def do_task():    # 異步任務的邏輯    await asyncio.sleep(1)    print("異步任務完成")@app.get("/items")async def read_item():    p = Thread(target=task, args=('線程1',))    p.start()      return {"data": "ok"}

在上面的代碼中使用  asyncio.run開啟新的事件循環去處理異步函數即可。但是之前那個朋友也說它嘗試夠使用在completion_callback中new一個事件循環(new_event_loop)然后用create_task或run_until_complete執行update_rp_file_status函數的時候,都不成功,或許可能得原因是它創建新的事件循環之后,沒有進行重新設置,所以會導致無法設置成功,也就是我們也可以改為如下代碼進行運行:xmK28資訊網——每日最新資訊28at.com

def task(name):    loop = asyncio.new_event_loop()  # 創建新的事件循環    asyncio.set_event_loop(loop)  # 設置新的事件循環為當前線程的事件循環    loop.run_until_complete(do_task())  # 在新的事件循環中運行異步任務

關于asyncio.run 和手動的設置創建事件循環

asyncio.run()是從Python 3.7版本引入的一個方便的函數,它用于運行異步函數。它自身會自動創建一個新的事件循環,并將異步函數添加到該事件循環中運行。在異步函數完成后,它會關閉事件循環并返回結果。而我們的xmK28資訊網——每日最新資訊28at.com

 loop = asyncio.new_event_loop()  # 創建新的事件循環    asyncio.set_event_loop(loop)  # 設置新的事件循環為當前線程的事件循環    loop.run_until_complete(do_task())  # 在新的事件循環中運行異步

是一種手動創建、設置和運行事件循環的方法包括:xmK28資訊網——每日最新資訊28at.com

使用asyncio.new_event_loop()創建一個新的事件循環。使用asyncio.set_event_loop(loop)將新創建的事件循環設置為當前線程的事件循環。使用loop.run_until_complete(do_task())在新的事件循環中運行異步任務,直到任務完成。xmK28資訊網——每日最新資訊28at.com

他們之間的區別在于使用asyncio.run()時,它會自動處理事件循環的創建、設置和關閉,非常方便。而手動創建、設置和運行事件循環需要更多的代碼來處理這些步驟,但也提供了更多的靈活性和控制權。xmK28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-57374-0.html關于FastAPI中在新線程里調用協成函數問題

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: .NET下優秀的IOC容器框架Autofac的使用方法,實例解析

下一篇: Vue3這個API慎用!可能會有性能問題!

標簽:
  • 熱門焦點
  • JavaScript 混淆及反混淆代碼工具

    介紹在我們開始學習反混淆之前,我們首先要了解一下代碼混淆。如果不了解代碼是如何混淆的,我們可能無法成功對代碼進行反混淆,尤其是使用自定義混淆器對其進行混淆時。什么是混
  • 分享六款相見恨晚的PPT模版網站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS網站旨在為全球Office用戶提供豐富的高品質原創PPT模板、實用文檔、數據圖表及個性化定制服務。優點:OfficePLUS是微軟官方網站,囊括PPT模板、Word模
  • Flowable工作流引擎的科普與實踐

    一.引言當我們在日常工作和業務中需要進行各種審批流程時,可能會面臨一系列技術和業務上的挑戰。手動處理這些審批流程可能會導致開發成本的增加以及業務復雜度的上升。在這
  • 破圈是B站頭上的緊箍咒

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之每年的暑期檔都少不了瞄準追劇女孩們的古偶劇集,2021年有優酷的《山河令》,2022年有愛奇藝的《蒼蘭訣》,今年卻輪到小破站抓住了追
  • 梁柱接棒兩年,騰訊音樂闖出新路子

    文丨田靜 出品丨牛刀財經(niudaocaijing)7月5日,企鵝FM發布官方公告稱由于業務調整,將于9月6日正式停止運營,這意味著騰訊音樂長音頻業務走向消亡。騰訊在長音頻領域還在摸索。為
  • iQOO 11S或7月上市:搭載“雞血版”驍龍8Gen2 史上最強5G Soc

    去年底,iQOO推出了“電競旗艦”iQOO 11系列,作為一款性能強機,iQOO 11不僅全球首發2K 144Hz E6全感屏,搭載了第二代驍龍8平臺及144Hz電競屏,同時在快充
  • iQOO Neo8系列今日官宣:首發天璣9200+ 全球安卓最強芯!

    在昨日舉行的的聯發科新一代旗艦芯片天璣9200+的發布會上,iQOO官方也正式宣布,全新的iQOO Neo8系列新品將全球首發搭載這款當前性能最強大的移動平臺
  • 蘋果140W USB-C充電器:采用氮化鎵技術

    據10 月 30 日 9to5 Mac 消息報道,當蘋果推出新的 MacBook Pro 2021 時,該公司還推出了新的 140W USB-C 充電器,附贈在 MacBook Pro 16 英寸機型的盒子里,也支
  • AI藝術欣賞體驗會在上海梅賽德斯奔馳中心音樂俱樂部上演

    光影交錯的鏡像世界,虛實幻化的視覺奇觀,虛擬偶像與真人共同主持,這些場景都出現在2019世界人工智能大會的舞臺上。8月29日至31日,“AI藝術欣賞體驗會”在上海
Top