Flask应用中处理异步事件(后台线程+事件循环)的方法(2)

在上一节,我们讲述了最简单最基础的后线程的建立,现在我们将进行拓展
Flask应用中处理异步事件(后台线程+事件循环)的方法(1)

在我们的实际应用当中,我们需要定义三个东西

  1. 一个多线程的信号旗,这里的信号旗指的是多线程编程中一个非常基础且重要的同步工具

    它只有两种状态:

    Clear (清除/未设置): 信号灯是红色的,旗子是放下的。

    Set (设置): 信号灯是绿色的,旗子是举起的。

    当进程调用event.wait(),如果此时事件是 "Clear" 状态(红灯),那么这个线程就会停下来,进入等待状态,被阻塞。

  2. 一个 循环的对象

  3. 一个新线程

接下来在这里我们看到了,有一个target参数,这个就是调用我们的一个说明书

python 复制代码
    # 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=True
        name="name"
    )
    loop_thread.start() # 启动这个新线程
    
    # 4. 主线程在这里暂停,等待后台线程通知
    logging.info("主线程正在等待 MCP 初始化...")
    is_ready = mcp_ready_event.wait(timeout=30.0) # 暂停30秒,等待加载

那么我们的说明书怎么写呢?这里举例mcp的连接初始化

初始化这里,无论成功还是失败,初始化流程走完后,调用 .set() 来释放正在 wait() 的主线程。

python 复制代码
# ... 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 类型的对象。
python 复制代码
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 事件循环的线程提交任务。

cpp 复制代码
asyncio.run_coroutine_threadsafe(coro, loop):
相关推荐
Qyee162 分钟前
【算法】基于中位数和MAD鲁棒平均值计算算法
python·算法
雨果talk29 分钟前
Spring Boot集成Mina的Socket资源管理:从稳定通信到高性能优化
spring boot·后端·性能优化
雨果talk29 分钟前
【一文看懂多模块Bean初始化难题】Spring Boot多模块项目中的Bean初始化难题:包名不一致的优雅解决方案
java·spring boot·后端·spring·springboot
Ai财富密码39 分钟前
【Python教程】CentOS系统下Miniconda3安装与Python项目后台运行全攻略
开发语言·python·numpy
大数据魔法师43 分钟前
豆瓣图书数据采集与可视化分析(四)- 豆瓣图书数据可视化(Pyecharts)
python·数据分析·数据可视化
databook1 小时前
掌握ChangeSpeed类:让数学动画速度随心而动!
python·动效
水花花花花花1 小时前
蓝桥杯国赛前一晚知识点准备(十六届python)
前端·javascript·python
CS创新实验室1 小时前
CPython 局部变量存储机制:从 “栈上存储“ 看语言实现差异
python···cpython·局部变量
ZHOU_WUYI1 小时前
flask JWT 认证
后端·flask·jwt
Python当打之年1 小时前
【61 Pandas+Pyecharts | 基于Apriori算法及帕累托算法的超市销售数据分析可视化】
python·信息可视化·数据分析·pandas·数据可视化