Python中前序函数为无限循环时如何并行运行后续函数
你当前遇到的阻塞问题本质是同步串行执行模式下,无限循环的采集任务会一直占用执行流,导致后续计算逻辑永远得不到调度。以下是可直接落地的解决方式:
多线程实现(推荐首选,改造成本最低)
WebSocket连接属于网络IO密集型任务,Python的threading模块完全可以胜任,网络IO等待阶段GIL会自动释放,不会和计算逻辑抢占资源。实现时仅需把采集任务放到独立守护子线程启动,主线程直接运行计算逻辑即可,两者完全并行:import threading # 导入两个文件中已经写好的业务函数 from ws_collect import run_websocket_collect from data_calc import run_realtime_calc if __name__ == "__main__": # 设置daemon=True标记守护线程,主程序退出时自动终止采集线程,避免残留孤儿进程 collect_thread = threading.Thread(target=run_websocket_collect, daemon=True) collect_thread.start() # 子线程启动后不会阻塞主线程,直接运行计算逻辑 run_realtime_calc()该方案不需要修改原有两个文件的任何业务代码,适合绝大多数计算逻辑为常规数据处理、查询统计的非CPU满载场景。
多进程实现(适配CPU密集型计算场景)
如果计算逻辑是大规模数值运算、实时AI推理这类会占满CPU核心的任务,多线程会受GIL限制无法发挥多核性能,此时可以用multiprocessing模块启动独立进程运行两个任务,进程间资源完全隔离,不受GIL约束:from multiprocessing import Process from ws_collect import run_websocket_collect from data_calc import run_realtime_calc if __name__ == "__main__": collect_process = Process(target=run_websocket_collect, daemon=True) collect_process.start() run_realtime_calc()由于你当前是通过数据库作为两个任务的数据中转媒介,不需要额外开发进程间通信逻辑,适配成本很低。注意多进程启动开销比线程高,常规IO场景没必要使用。
异步协程实现(性能最优,需改造业务代码)
如果你使用的WebSocket库原生支持异步(比如websockets、aiohttp),可以把采集和计算逻辑都改写为异步协程,通过asyncio事件循环实现单线程内的并发调度,资源开销是所有方案中最低的:import asyncio # 注意:需要将原有两个同步业务函数改造为async异步函数 from ws_collect import async_run_ws_collect from data_calc import async_run_realtime_calc async def main(): # 并发调度两个协程任务 await asyncio.gather( async_run_ws_collect(), async_run_realtime_calc() ) if __name__ == "__main__": asyncio.run(main())该方案适合对并发性能要求高、后续需要扩展更多实时任务的生产场景,缺点是需要重构原有同步代码,改造成本较高。
系统层多进程启动(零代码侵入,适合临时调试)
不需要编写第三个统一调用的Python文件,直接在操作系统层面启动两个独立Python进程即可:调试阶段可以打开两个终端分别运行两个脚本;Linux/macOS可以编写shell脚本批量启动,Windows可以通过bat脚本实现同样效果。以Linux shell脚本为例:#!/bin/bash python ws_collect.py & python data_calc.py该方案完全不需要修改已有代码,缺点是任务管理不便,停止服务时需要手动查找并终止两个进程,不适合生产环境使用。
选型参考:90%的常规业务场景直接选择多线程方案即可,代码改动最少、稳定性足够;如果计算逻辑CPU占用极高就选多进程;构建高性能生产服务可以投入成本重构为异步协程架构;临时调试验证逻辑直接开两个终端运行最方便。
内容的提问来源于stack exchange,提问作者Sudarshan Gope

