Flask應用中處理異步事件(后臺線程+事件循環)的方法(2)

在上一節,我們講述了最簡單最基礎的后線程的建立,現在我們將進行拓展
Flask應用中處理異步事件(后臺線程+事件循環)的方法(1)
在我們的實際應用當中,我們需要定義三個東西

  1. 一個多線程的信號旗,這里的信號旗指的是多線程編程中一個非常基礎且重要的同步工具
    它只有兩種狀態:
    Clear (清除/未設置): 信號燈是紅色的,旗子是放下的。
    Set (設置): 信號燈是綠色的,旗子是舉起的。
    當進程調用event.wait(),如果此時事件是 “Clear” 狀態(紅燈),那么這個線程就會停下來,進入等待狀態,被阻塞。

  2. 一個 循環的對象

  3. 一個新線程

接下來在這里我們看到了,有一個target參數,這個就是調用我們的一個說明書

# 1. 創建一個線程同步工具mcp_ready_event = threading.Event()# 2. 創建一個新的 asyncio 事件循環對象background_event_loop = asyncio.new_event_loop()# 3. 創建一個新線程,目標是運行 start_event_loop 函數loop_thread = threading.Thread(target=start_event_loop, args=(background_event_loop, mcp_ready_event),daemon=Truename="name")loop_thread.start() # 啟動這個新線程# 4. 主線程在這里暫停,等待后臺線程通知logging.info("主線程正在等待 MCP 初始化...")is_ready = mcp_ready_event.wait(timeout=30.0) # 暫停30秒,等待加載

那么我們的說明書怎么寫呢?這里舉例mcp的連接初始化
初始化這里,無論成功還是失敗,初始化流程走完后,調用 .set() 來釋放正在 wait() 的主線程。

# ... existing code ...
async def initialize_mcp_connection(ready_event: threading.Event):"""在應用啟動時啟動MCP服務器并建立一個持久的會話。完成后通過 event 通知主線程。"""# ...try:# 初始化代碼except Exception as e:# ... 錯誤處理 ...finally:logging.info("MCP 初始化過程結束,通知主線程。")ready_event.set() 

初始化完畢之后,我們就進行接下來的開始線程
這里的參數 loop: asyncio.AbstractEventLoop 和 ready_event: threading.Event 是什么意思?
這是一種現代 Python 的語法,叫做 類型提示 (Type Hinting)。它本身不強制任何東西,但它極大地增強了代碼的可讀性和可維護性,并且能被很多開發工具利用來進行代碼檢查。

  • loop: asyncio.AbstractEventLoop: 這行代碼的意思是,我們期望 loop 這個參數是一個 asyncio.AbstractEventLoop 類型的對象。它告訴任何閱讀或調用這個函數的人:“請給我一個 asyncio 的事件循環對象。”
  • ready_event: threading.Event: 同理,這表示我們期望 ready_event 這個參數是一個我們剛才講的 threading.Event 類型的對象。
def start_event_loop(loop: asyncio.AbstractEventLoop, ready_event: threading.Event):"""在一個線程中啟動事件循環,并在啟動時安排MCP初始化。"""asyncio.set_event_loop(loop)    loop.create_task(initialize_mcp_connection(ready_event))    logging.info("后臺事件循環已啟動,MCP 初始化任務已安排。")loop.run_forever()

需要注意這里start_event_loop 函數中的 loop,和主線程中的 background_event_loop,雖然名字不同,但它們指向的是內存中同一個事件循環對象。

最后只需要運行一個專門用于從一個普通線程向一個正在運行 asyncio 事件循環的線程提交任務。

asyncio.run_coroutine_threadsafe(coro, loop):

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83955.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83955.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83955.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++(面向對象編程)

思維導圖 面向對象 1.面向對象思想 概念:面向對象編程(OOP)是一種以對象為基礎的編程范式,強調將數據和操作數據的方法封裝在一起。這就是上篇文章講過的。面向過程是以“怎么解決問題”為核心,而面向對象思想在于“誰…

驅動程序無法通過使用安全套接字層(SSL)加密與 SQL Server 建立安全連接,

驅動程序無法通過使用安全套接字層(SSL)加密與 SQL Server 建立安全連接,Error: “The server selected protocol version TLS10 is not accepted by client preferences [TLS13,TLS12]”. ClientConnectionId:d5fd8d69-ae88-4055-9f6d-6e8515224ce2】。 基本上就是…

【三大前端語言之一】交互:JavaScript詳解

【三大前端語言之一】交互:JavaScript詳解 在學習完HTML和CSS之后,最后一門前端語言——JavaScript,是重中之重。HTML負責頁面結構,CSS負責頁面樣式,而JavaScript則賦予網頁“生命”,讓網頁可以動起來、響…

LangChain面試內容整理-知識點12:檢索器(Retriever)接口與實現

在LangChain中,檢索器(Retriever)是一個抽象接口,負責根據用戶查詢從數據源中檢索相關文檔。可以把Retriever理解為“搜索工具”:給它一個未經結構化的查詢文本(如用戶問題),它返回一組與之相關的 Document 對象。內部可以基于向量相似度、數據庫查詢、甚至網絡搜索。 …

LLVM前端和優化層

文章目錄 LLVM ArchitectueLLVM 前端Lexical Analysis詞法分析Syntactic analysis 語法分析Syntactic Analyze語義分析 LLVM 優化層Pass 基礎概念Pass 依賴關系Pass API 總結 LLVM Architectue LLVM 前端 LLVM 的前端其實是把源代碼也就是 C、C、Python 這些高級語言變為編譯器…

工作流和Agent 的區別與聯系

工作流和智能體可能讓人混淆的地方就是他們都可能有大模型的加持,都可能有工具的加入供大模型調用,本文做一下對比和聯系 工作流 (Workflow) 定義: 工作流是一系列預定義、結構化且可重復的步驟或任務,旨在完成特定的業務目標或解…

leetcode--用StringBulider反轉字符串單詞的巧妙解法

反轉字符串中的單詞 這道題理想中的操作方式就是先去除前導和尾隨空格,之后設一個尾指針,往前檢索,掃到一個單詞就把這個單詞放到字符串的第一個位置。 很明顯,java中我們不能直接對字符串進行修改,而我們想實現一個一…

連鎖零售行業智慧能源管理解決方案:精準管控,讓每一度電創造價值

在連鎖超市、便利店等業態中,門店分布廣、用能場景復雜、管理成本高是普遍難題。傳統能源管理模式依賴人工抄表與分散管理,存在數據滯后、響應效率低、安全隱患難排查等問題。以某全國幾千家門店的連鎖便利店為例,其面臨的挑戰包括&#xff1…

在 PostgreSQL 中實現 `lck`, `special`, `item` 與 `org_id` 或 `user_id` 組合唯一的約束

在 PostgreSQL 中實現 lck, special, item 與 org_id 或 user_id 組合唯一的約束 要實現 lck, special, item 這三個字段必須與 org_id 或 user_id 中的一個(但不能同時)組合唯一的約束,你需要創建以下約束: 方案1:使…

g++ a.cpp -o a ‘pkg-config --cflags --libs opencv4‘/usr/bin/ld: 找不到 沒有那個文件或目錄

這個錯誤表明 pkg-config 命令沒有正確執行,導致編譯器無法找到 OpenCV 的庫文件和頭文件路徑。pkg-config 是一個工具,用于查詢已安裝庫的編譯和鏈接選項。如果 pkg-config 無法找到 OpenCV 的配置文件,就會導致這個錯誤。 以下是解決這個問…

定制平板在智能家居中能做些什么?全面解析其核心功能

大家有沒有發現,現在智能家居越來越普及了,很多家庭都在逐步升級自己的居住體驗。而在這一過程中,一種設備正悄悄地取代我們以前常用的開關面板和手機APP,成為整個家庭智能控制的核心,這就是——定制平板。 它可不是我…

【通俗易懂】Linux 線程調度策略詳解

引言:CPU是廚房,調度器是主廚 要真正理解Linux如何處理成千上萬個并發任務,不妨把它想象成一個繁忙的專業廚房。這個比喻不僅能讓抽象概念變得具體,更能揭示其背后深刻的設計哲學。 廚房 (The Kitchen): 代表整個計算機系統。 廚…

筆記本電腦安裝win10哪個版本好_筆記本裝win10專業版圖文教程

筆記本電腦安裝win10哪個版本好?筆記本還是建議安裝win10專業版。Win分為多個版本,其中家庭版(Home)和專業版(Pro)是用戶選擇最多的兩個版本。win10專業版在功能以及安全性方面有著明顯的優勢,所…

微服務循環依賴調用引發的血案

問題表現 最近的迭代轉測后遇到了一個比較有意思的問題。在測試環境整體運行還算平穩,但是過一段時間之后,就開始有接口超時了,日志中出現非常多的 “java.net.SocketTimeoutException: Read timed out”。試了幾次重啟大法,每次…

LeetCode - 852. 山脈數組的峰頂索引

題目 852. 山脈數組的峰頂索引 - 力扣&#xff08;LeetCode&#xff09; 思路 使用二分查找來定位峰頂 對于中間元素&#xff0c;比較它與其右側元素的大小&#xff1a; 如果 arr[mid] < arr[mid1]&#xff0c;說明我們在上坡階段&#xff0c;峰頂在右側 如果 arr[mid…

國產ARM/RISCV與OpenHarmony物聯網項目(二)網關數據顯示

本文需要Web服務器開發基礎&#xff0c;可參考下述博文&#xff1a; 物聯網網關Web服務器--lighttpd服務器部署與應用測試 物聯網網關Web服務器--CGI開發接口 一、數據顯示界面與功能設計 1、功能設計說明 程序代碼結構如下&#xff0c;調用關系見彩色部分標示。 數據顯示界面…

Robyn高性能Web框架系列01:Robyn快速入門

Robyn快速入門 安裝 Robyn1、僅安裝基礎 HTTP 路由功能2、帶擴展功能的安裝 第一個Robyn程序1、創建Robyn應用2、Say Hello!3、啟動Robyn應用 Python世界從來不缺少對于性能的追求&#xff0c;Robyn就是其中之一&#xff0c;它將 Python 的異步功能與 Rust 相結合&#xff0c;在…

微信小程序 -----無限新增刪除,同時算出總合算金額。

<view class="refuelMoney-main" style="padding-bottom: 200rpx;"><!-- <view class="add_record">添加加油記錄</view> --><view class="refuel-itemTextArea"><text style="width: 35%;&quo…

linux “Permission Denied“解決方案

Linux 編譯錯誤排查 在軟件開發過程中&#xff0c;編譯錯誤和版本控制問題是開發者每天都會遇到的挑戰。本文將結合實際案例&#xff0c;詳細講解 Linux 環境下常見編譯錯誤的排查方法 權限拒絕錯誤&#xff08;Permission Denied&#xff09; 當執行腳本或程序時&#xff0…

【慧游魯博】【15】后臺管理系統功能完善:儀表盤、多模態交互日志、簡單問答詞條管理

文章目錄 本次更新多模態交互日志效果涉及代碼文件 儀表盤&#xff08;部分&#xff09;效果涉及代碼文件 簡單問答服務詞條管理效果涉及代碼文件 本次更新 代碼真的太多太多了&#xff0c;不放代碼了 多模態交互日志 數據概覽與篩選功能 時間范圍篩選&#xff1a;提供"…