线程池限制来源解析:为何multiprocessing.pool.ThreadPool最大为11689?
ThreadPool最大线程数11689的来源解析
你碰到的这个11689的线程数上限,可不是Python自带的什么特殊常量,完全是操作系统层面的资源限制在背后起作用——Python的ThreadPool底层依赖系统原生线程API(比如Linux下的pthread),当系统没法再给进程分配新线程的资源时,就会抛出RuntimeError: can't start new thread错误,而11689就是你的系统刚好耗尽某类资源时的临界值。
具体来说,这个数值通常由以下几个系统资源限制共同决定:
- 线程栈空间的总占用:每个线程默认会分配一块独立的栈内存(Linux下默认栈大小可以用
ulimit -s命令查看,常见值是8MB或1MB)。单个进程的虚拟地址空间是有限的(哪怕是64位系统,进程可用的地址空间也不是无限的),当所有线程的栈内存总和接近这个地址空间上限时,就没法再创建新线程。比如如果你的系统栈大小是1MB,11689个线程的总栈内存约为11GB,这在64位进程的地址空间里是合理的临界值。 - 单个进程的线程数上限:Linux系统中,线程属于轻量级进程,用户级别的限制
ulimit -u会管控单个用户(或进程)能创建的最大进程/线程数。如果你的系统这个值刚好是11689,那这就是直接触发限制的原因。 - 系统全局线程总数限制:系统层面有一个全局的线程数上限,由
/proc/sys/kernel/threads-max控制,这个值是系统根据内存容量计算出来的。如果这个全局上限接近11689,也会导致单个进程无法创建更多线程。 - 内存映射数量限制:每个线程的栈对应一个内存映射,系统的
/proc/sys/vm/max_map_count限制了单个进程能拥有的内存映射总数,当这个数量耗尽时,也会触发无法创建线程的错误。
你可以通过执行以下命令来验证你的系统对应限制,就能找到11689这个数值的直接来源:
# 查看默认线程栈大小 ulimit -s # 查看单个用户允许的最大进程/线程数 ulimit -u # 查看系统全局线程总数上限 cat /proc/sys/kernel/threads-max # 查看单个进程允许的内存映射数量上限 cat /proc/sys/vm/max_map_count
简单总结:11689是你的系统各项资源限制共同作用下的临界值,哪个资源先被耗尽,哪个对应的数值就是你看到的线程数上限。
内容的提问来源于stack exchange,提问作者Martin Thoma
相关产品推荐
相关产品推荐

