日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

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

關(guān)于FastAPI中在新線程里調(diào)用協(xié)成函數(shù)問題

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

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

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

gpQ28資訊網(wǎng)——每日最新資訊28at.com

大致的代碼如下所示:gpQ28資訊網(wǎng)——每日最新資訊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也是異步函數(shù),但是里面涉及到webdav3庫的異步的調(diào)用,如下代碼所示:gpQ28資訊網(wǎng)——每日最新資訊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))  .........

容納后在調(diào)用upload_async的使用,需要進行任務處理完成的回調(diào),也就是completion_callback函數(shù),它的代碼如下:gpQ28資訊網(wǎng)——每日最新資訊28at.com

def completion_callback(old_file_dir, file_name):    pss

它的問題就是在completion_callback還有一個異步的函數(shù)需要調(diào)用的時候就遇到問題了:gpQ28資訊網(wǎng)——每日最新資訊28at.com

(1) 我無法在upload_async上傳文件完成后的回調(diào)函數(shù)使用async,即 async def completion_callbackgpQ28資訊網(wǎng)——每日最新資訊28at.com

(2) 我在completion_callback中獲取當前事件循環(huán),因為執(zhí)行這個回調(diào)函數(shù)的時候,控制臺打印當前沒有事件循環(huán)gpQ28資訊網(wǎng)——每日最新資訊28at.com

3) 我在completion_callback中new一個事件循環(huán)(new_event_loop)然后用create_task或run_until_complete執(zhí)行update_rp_file_status函數(shù)的時候,都不成功:gpQ28資訊網(wǎng)——每日最新資訊28at.com

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

問題探究

其實這個問題本質(zhì)其實就是關(guān)于 client.upload_async中啟用了新的線程去異步處理了,導致了開啟了新的線程的問題,如下 client.upload_async的代碼:gpQ28資訊網(wǎng)——每日最新資訊28at.com

gpQ28資訊網(wǎng)——每日最新資訊28at.com

由此可見,問題肯本原因在于是因為我們是在新線程中調(diào)用了異步函數(shù),而新線程沒有自己的事件循環(huán)導致的。gpQ28資訊網(wǎng)——每日最新資訊28at.com

回到事件循環(huán)的本身上,我們知道首先需要知道一點:gpQ28資訊網(wǎng)——每日最新資訊28at.com

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

from fastapi import FastAPIimport asyncioapp = FastAPI()from threading import Thread  # 創(chuàng)建線程的模塊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())也會遇到如下類似的錯誤提示:gpQ28資訊網(wǎng)——每日最新資訊28at.com

gpQ28資訊網(wǎng)——每日最新資訊28at.com

問題解決

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

from fastapi import FastAPIimport asyncioapp = FastAPI()from threading import Thread  # 創(chuàng)建線程的模塊def task(name):    print(asyncio.get_event_loop())    # 嘗試去執(zhí)行異步任務    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開啟新的事件循環(huán)去處理異步函數(shù)即可。但是之前那個朋友也說它嘗試夠使用在completion_callback中new一個事件循環(huán)(new_event_loop)然后用create_task或run_until_complete執(zhí)行update_rp_file_status函數(shù)的時候,都不成功,或許可能得原因是它創(chuàng)建新的事件循環(huán)之后,沒有進行重新設(shè)置,所以會導致無法設(shè)置成功,也就是我們也可以改為如下代碼進行運行:gpQ28資訊網(wǎng)——每日最新資訊28at.com

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

關(guān)于asyncio.run 和手動的設(shè)置創(chuàng)建事件循環(huán)

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

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

是一種手動創(chuàng)建、設(shè)置和運行事件循環(huán)的方法包括:gpQ28資訊網(wǎng)——每日最新資訊28at.com

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

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

本文鏈接:http://www.www897cc.com/showinfo-26-57374-0.html關(guān)于FastAPI中在新線程里調(diào)用協(xié)成函數(shù)問題

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

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

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

標簽:
  • 熱門焦點
  • 俄羅斯:將審查iPhone等外國公司設(shè)備 保數(shù)據(jù)安全

    iPhone和特斯拉都屬于在各自領(lǐng)域領(lǐng)頭羊的品牌,推出的產(chǎn)品也也都是數(shù)一數(shù)二的,但對于一些國家而言,它們的產(chǎn)品可靠性和安全性還是在限制范圍內(nèi)。近日,俄羅斯聯(lián)邦通信、信息技術(shù)
  • 6月安卓手機好評榜:魅族20 Pro蟬聯(lián)冠軍

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數(shù)據(jù)來源安兔兔評測,收集時間2023年6月1日至6月30日,僅限國內(nèi)市場。第一名:魅族20 Pro好評率:95%5月份的時候魅族20 Pro就是
  • 從 Pulsar Client 的原理到它的監(jiān)控面板

    背景前段時間業(yè)務團隊偶爾會碰到一些 Pulsar 使用的問題,比如消息阻塞不消費了、生產(chǎn)者消息發(fā)送緩慢等各種問題。雖然我們有個監(jiān)控頁面可以根據(jù) topic 維度查看他的發(fā)送狀態(tài),
  • 分享六款相見恨晚的PPT模版網(wǎng)站, 祝你做出精美的PPT!

    1、OfficePLUSOfficePLUS網(wǎng)站旨在為全球Office用戶提供豐富的高品質(zhì)原創(chuàng)PPT模板、實用文檔、數(shù)據(jù)圖表及個性化定制服務。優(yōu)點:OfficePLUS是微軟官方網(wǎng)站,囊括PPT模板、Word模
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 講故事上個月我寫過一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,當時用的是 GDIView + WinDbg 把問題搞定,前者用來定位泄露資源,后者用來定位泄露代碼,后面有朋友反
  • Python異步IO編程的進程/線程通信實現(xiàn)

    這篇文章再講3種方式,同時講4中進程間通信的方式一、 Python 中線程間通信的實現(xiàn)方式共享變量共享變量是多個線程可以共同訪問的變量。在Python中,可以使用threading模塊中的L
  • 2023年,我眼中的字節(jié)跳動

    此時此刻(2023年7月),字節(jié)跳動從未上市,也從未公布過任何官方的上市計劃;但是這并不妨礙它成為中國最受關(guān)注的互聯(lián)網(wǎng)公司之一。從2016-17年的抖音強勢崛起,到2018年的“頭騰
  • 簽約井川里予、何丹彤,單視頻點贊近千萬,MCN黑馬永恒文希快速崛起!

    來源:視聽觀察永恒文希傳媒作為一家MCN公司,說起它的名字來,可能大家會覺得有點兒陌生,但是說出來下面一串的名字之后,或許大家就會感到震驚,原來這么多網(wǎng)紅,都簽約這家公司了。根
  • 三星電子Q2營收60萬億韓元 存儲業(yè)務營收同比仍下滑超過50%

    7月27日消息,據(jù)外媒報道,從三星電子所發(fā)布的財報來看,他們主要利潤來源的存儲芯片業(yè)務在今年二季度仍不樂觀,營收同比仍在大幅下滑,所在的設(shè)備解決方案
Top 主站蜘蛛池模板: 和顺县| 大埔县| 通辽市| 镇远县| 丽江市| 林州市| 寿光市| 丹寨县| 金华市| 淮南市| 青州市| 龙南县| 化隆| 新津县| 西吉县| 璧山县| 敦化市| 慈溪市| 灵川县| 湘乡市| 资源县| 锡林郭勒盟| 酒泉市| 临夏市| 綦江县| 枣阳市| 油尖旺区| 马尔康县| 乌兰浩特市| 宜宾县| 石屏县| 金平| 清河县| 区。| 潮州市| 于田县| 乡宁县| 浠水县| 铜梁县| 宜君县| 资源县|