You need to enable JavaScript to run this app. Python协程任务中能否启动新线程执行数据保存以避免阻塞重连逻辑
优惠活动
大模型
产品
解决方案
定价
更多

Python协程任务中能否启动新线程执行数据保存以避免阻塞重连逻辑

问题根因

之前尝试用_thread.start_new_thread启动保存流程依然阻塞重连逻辑,核心原因有两个:

  • 保存逻辑本身存在严重性能瓶颈:你现在用的df.append()循环拼接DataFrame是O(n²)复杂度的操作,数据量越大耗时越高,这类高CPU占用的操作运行时会持续占用GIL,哪怕跑在子线程,也会频繁抢占协程事件循环所在主线程的执行权限,导致重连检查逻辑没法及时调度。
  • 读写流程存在锁竞争:你在保存时直接遍历读取原有queue.Queue中的数据,而协程的实时行情写入操作会持续操作同一个队列,双方争抢队列互斥锁时会产生大量阻塞延迟。

只要存在这两个问题,哪怕开了独立线程,也没法真正做到不阻塞重连逻辑的保存效果。

不阻塞重连的实现方式

正确隔离保存任务

  • 不要用裸的_thread模块启动保存流程,改用asyncio.to_thread()将整个保存逻辑丢到独立线程池执行。这个API是协程原生的非阻塞调用,触发保存后立刻把控制权交回给事件循环,不会等待保存流程跑完,完全不会卡住重连逻辑的调度。
  • 消除队列读写的锁竞争:在断线事件触发需要保存的瞬间,先对每个RIC对应的队列做原子快照——一次性取出原队列里的所有数据,同时给对应RIC换上全新的空队列,供重连后写入新的行情数据,再把快照出来的旧数据传给保存线程。这样保存线程慢慢处理旧数据的时候,和协程的新数据写入操作完全不会抢同一把锁,没有任何竞争开销。

从根源降低保存耗时

  • 彻底替换循环df.append()拼DataFrame的写法:把从队列取出的逐笔数据先放到普通Python列表里,循环结束后一次性把列表转成DataFrame,单步转换的耗时是原来append写法的几十分之一。
  • 用流式追加写入替代全量攒盘:不需要依赖pystore这类存在追加功能缺陷的存储,可以直接用原生文件追加、Parquet批量追加、SQLite批量插入的方式持久化数据,写入过程不需要把所有缓存数据全部加载进内存拼大表,IO和CPU耗时都会大幅降低。
  • 优化现有write_data的文件操作逻辑:现在每次写文件都要遍历计算已有文件数、新建文件的流程本身就有额外开销,可以提前维护每个RIC对应的文件句柄,缓存的新数据到了一定量级就直接追加写入文件,不用等断线时一次性处理所有缓存数据。
避坑要点
  • 不要在保存的子线程里直接调用协程上下文内的接口,避免出现跨线程操作事件循环的报错。
  • 不要在协程事件循环所在的主线程执行任何pandas计算、文件IO类操作,哪怕是几毫秒的单次延迟,累计后都会拉长重连的整体耗时。

内容的提问来源于stack exchange,提问作者K' Chau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.13 15:57:05