Numpy主进程线程池大小在fork操作发生时出现异常变化
NumPy调用fork后主进程BLAS线程池消失问题的成因与解决方案
问题成因
- 该问题是OpenBLAS库的历史版本bug导致:你使用的NumPy 1.18.4默认绑定的OpenBLAS版本处于0.3.7~0.3.9的问题区间,该版本的OpenBLAS错误注册了
fork()系统调用的钩子函数,本应该仅在fork产生的子进程中清理线程池资源,逻辑写反后错误销毁了*父进程(也就是你说的主进程)*的线程池。 - 正常
fork()的语义不会修改父进程的任何线程状态,该行为完全是依赖库的错误实现导致,和Python、Linux系统的fork逻辑无关。
验证方法
可以运行以下代码确认你的NumPy绑定的BLAS实现:
import numpy as np np.__config__.show()
如果输出中包含openblas信息且版本号低于0.3.10,即可确认是该bug导致。
解决方案
- 永久修复:升级NumPy到1.21及以上版本,新版NumPy默认绑定的OpenBLAS已修复该问题;也可单独将OpenBLAS升级到0.3.10及以上版本后重新编译NumPy。
- 临时规避:导入NumPy前设置环境变量
OPENBLAS_NUM_THREADS=1,强制OpenBLAS不启动多线程池,不会触发线程销毁逻辑,但会损失NumPy的并行计算性能。
内容的提问来源于stack exchange,提问作者justinokamoto
相关产品推荐
相关产品推荐

