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

使用Python多进程时调用sklearn LinearRegression fit方法子进程挂起

解决多进程中LinearRegression.fit挂起的问题

我之前也碰到过一模一样的情况!这个问题的根源在于sklearn的LinearRegression底层依赖Numpy的BLAS/LAPACK多线程加速,而Python多进程环境下这种多线程会和子进程的启动机制冲突,导致死锁挂起,而决策树回归器本身是单线程运行,所以没这个麻烦。结合你的环境版本,给你几个靠谱的解决办法:

方法1:在子进程中强制限制Numpy线程数

在子进程的任务函数开头,先把Numpy的线程池大小设为1,避免多线程竞争:

import numpy as np
import multiprocessing as mp
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor

def exp(X,y):
    model = LinearRegression()
    model.fit(X,y)
    print('fitted')

def job(X,y):
    # 强制Numpy只用1个线程,避免多进程+多线程的冲突
    np.set_num_threads(1)
    model = LinearRegression()
    model.fit(X,y)
    print('fitted (child process)')

if __name__ == '__main__':
    n_obs = 100
    X = np.random.random((n_obs,1))
    y = np.random.random((n_obs))
    exp(X,y)
    # 把进程创建的代码放到if __name__ == '__main__'里面!
    p = mp.Process(target = job, args=(X,y))
    p.start()
    p.join()
    print('done')

方法2:全局限制Numpy线程数(更省心)

如果你不想在每个子进程里都写一遍,也可以在主程序最开头就设置全局的Numpy线程数,这样所有子进程都会继承这个设置:

import numpy as np
# 全局设置Numpy只用1个线程
np.set_num_threads(1)
import multiprocessing as mp
from sklearn.linear_model import LinearRegression

# 后面的代码和修正后的版本一致...

额外注意:你的代码的一个小问题

原来的代码里把p = mp.Process(...放在了if __name__ == '__main__':外面,这在Windows系统下会触发重复创建进程的问题(因为Windows的multiprocessing是spawn模式,会重新导入整个模块),虽然这不一定是挂起的直接原因,但也是必须修正的隐患——把进程创建、启动的逻辑都放到if __name__ == '__main__':块里面就没问题了。

为什么LinearRegression会有这个问题?简单说:LinearRegression的fit方法会调用Numpy的矩阵运算,而默认的Numpy后端(比如OpenBLAS)会自动开启多个线程来加速;当子进程启动时,会继承父进程的线程池状态,加上Python的GIL(全局解释器锁)在多线程中的切换,就容易出现线程死锁,导致进程挂起不动。而DecisionTreeRegressor的拟合过程是纯单线程的,不会触发这个冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 22:12:48