You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多进程股票策略代码在新Win10电脑上无法终止求助

多进程股票策略代码在Windows环境下进程挂起的排查与解决思路

问题背景

我开发的多进程股票策略代码在两台Windows 10(Python 3.10)机器上运行正常,但在新电脑执行生成PNG图片的逻辑时出现异常——进程永远无法终止,疑似某个子进程未正常结束。已确认三台机器的Python包版本完全一致,运行日志前期内容完全相同,正常机器进程退出码为0,耗时约19秒。核心多进程执行代码如下:

def run_strategy_parallel(self):
    """Run the strategy for multiple tickers using multiple threads."""
    self.input_data_handler.download_stock_data_parallel()

    tickers = self.input_data_handler.get_tickers_list()
    start_time = datetime.now()
    print(f"{40*'='}\nStarting time: {start_time}\n{40*'-'}")
    with ProcessPoolExecutor() as executor:
        results = executor.map(self._process_strategy_wrapper, tickers)

    self._write_output(df=pd.concat(results))

    timer_end = datetime.now()
    print(f"{40*'-'}\nFinishing time: {timer_end}")
    print(f"Time taken: {timer_end - start_time}")

def _process_strategy_wrapper(self, ticker) -> pd.DataFrame:
    """Wrapper to catch and print exceptions from the strategy."""
    try:
        return self._process_strategy(ticker=ticker)
    except Exception as e:
        print(80*"=")
        print(f"Error processing strategy for ticker: {ticker}")
        print(80*"-")
        traceback.print_exception(e)

def _process_strategy(self, ticker: str) -> pd.DataFrame:
    df_stock = self.input_data_handler.get_stock_data(ticker=ticker)
    if df_stock is None:
        print(f"No stock data available for {ticker}. Skipping...")
        return pd.DataFrame()

    df_buy = self.buy_signal_finder.run(
        ticker=ticker,
        stock_data=df_stock,
    )

    df_sell = self.sell_signal_finder.run(
        ticker=ticker,
        stock_data=df_stock,
    )

    return pd.concat([df_buy, df_sell])

排查思路

  • 定位卡住的子进程
    在_process_strategy中添加详细日志,记录每个ticker的PNG生成开始、结束时间,确认是所有进程挂起还是特定ticker的进程卡住。
  • 验证多进程资源配置
    新电脑CPU核心数可能与旧机器差异大,ProcessPoolExecutor默认使用全部核心,可能引发资源竞争。手动指定max_workers(比如设为4或8),观察是否还会挂起。
  • 检查PNG生成的系统依赖
    即使Python包版本一致,Windows底层依赖(如libpng、绘图库的系统动态库)可能缺失。单独运行PNG生成的代码片段,验证是否能正常执行。
  • 排查进程间通信阻塞
    executor.map会等待所有子进程返回结果,若返回的DataFrame包含不可序列化对象或数据量过大,可能导致通信阻塞。临时修改代码,让子进程只执行PNG生成不返回数据,测试是否还会挂起。
  • 查看系统事件日志
    打开Windows事件查看器,检查应用程序日志中是否有Python进程的崩溃、权限报错或资源耗尽记录。
  • 测试单进程模式
    临时替换多进程为单进程循环执行,若单进程正常,说明问题出在多进程调度或进程交互环节。

解决建议

  • 给任务添加超时机制
    改用executor.submit配合as_completed,给每个任务设置超时,避免单个进程卡住导致整体挂起:
    from concurrent.futures import as_completed
    
    with ProcessPoolExecutor(max_workers=4) as executor:
        futures = {executor.submit(self._process_strategy_wrapper, ticker): ticker for ticker in tickers}
        results = []
        for future in as_completed(futures, timeout=30):
            ticker = futures[future]
            try:
                res = future.result()
                results.append(res)
            except Exception as e:
                print(f"Task for {ticker} timed out or failed: {e}")
    
  • 配置绘图库的多进程兼容模式
    若用matplotlib生成PNG,在子进程的绘图代码开头添加后端配置,避免GUI相关阻塞:
    import matplotlib
    matplotlib.use('Agg')  # 使用非交互式后端
    
  • 确保文件写入权限
    明确指定PNG输出目录为用户有权限的路径(如os.path.expanduser("~/output")),并添加文件写入的异常捕获。
  • 避免子进程共享全局对象
    Windows多进程通过pickle复制对象,若input_data_handler等实例包含不可序列化资源(如文件句柄),会导致异常。改为在子进程中重新初始化这些对象,而非依赖父进程实例。

内容的提问来源于stack exchange,提问作者Artrade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:10:24