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

scikit-learn中n_jobs设为-1或大值时出现队列线程异常问题

Fix for ValueError: need at most 63 handles when using n_jobs=-1 in scikit-learn (Windows)

这个问题我之前在Windows环境下处理过,根源是Windows系统底层API的限制:sklearn依赖的loky多进程库,在Windows上会调用WaitForMultipleObjects函数,而这个函数最多只能同时等待63个句柄。当你设置n_jobs=-1(会使用所有CPU核心)或者设置的数值过大时,创建的进程数加上其他系统句柄会超过63,就会触发这个错误。

下面是几个可行的解决办法:

1. 限制n_jobs的最大值

直接把n_jobs设置为不超过60的数值(留几个句柄给系统进程),或者动态取CPU核心数和60的最小值,避免超过限制。比如修改你的代码:

import os
from sklearn import datasets
from sklearn.model_selection import cross_validate, StratifiedKFold
from sklearn.linear_model import RidgeClassifier

iris = datasets.load_iris()
iris_X = iris.data
iris_y = iris.target
skf = StratifiedKFold(n_splits=5, random_state=0, shuffle=True)
scoring = {'accuracy': 'accuracy'}
model_ridge = RidgeClassifier(random_state=0)
# 动态设置n_jobs为CPU核心数和60的最小值
max_workers = min(os.cpu_count(), 60)
scores = cross_validate(estimator=model_ridge, X=iris_X, y=iris_y, scoring=scoring, cv=skf.split(iris_X, iris_y), n_jobs=max_workers)

2. 改用线程作为并行后端

如果你的模型是非CPU密集型(或者不受Python GIL限制,比如sklearn多数基于C扩展的模型已经释放了GIL),可以改用线程后端替代进程,这样不会触发Windows的句柄限制。只需要在cross_validate里加上backend="threading"参数:

scores = cross_validate(estimator=model_ridge, X=iris_X, y=iris_y, scoring=scoring, cv=skf.split(iris_X, iris_y), n_jobs=-1, backend="threading")

注意:如果你的模型是纯Python编写的CPU密集型任务,线程可能不会带来性能提升,但至少能解决这个错误。

3. 检查并更新相关依赖库

虽然你已经重装过scikit-learn和joblib,但可以尝试更新到最新稳定版,新版本的loky可能对Windows的句柄限制做了优化:

pip install --upgrade scikit-learn joblib loky

补充说明

之前n_jobs=-1能正常工作,可能是因为之前你的系统进程占用的句柄数更少,或者当时的CPU核心数更少,总句柄数没超过63。近期可能因为系统更新、后台进程增加或者CPU核心数识别变化(比如启用了超线程),导致总句柄数突破了限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:04:24