docker启动线程创建异常 pthread_create EPERM | RuntimeError: can‘t start new thread
·
直接说答案,着急就复制过去使用
docker配置 增加对应权限配置参数即可
--privileged
如果上述不行,docker配置 使用组合方式
--privileged \
--ulimit nproc=65535:65535 \
--ulimit nofile=65535:65535 \
详细解释
下面逐项解释这些 Docker 参数的作用、底层含义、适用场景,以及可能的副作用。
1. --privileged
--privileged
作用
给容器“接近宿主机 root”的权限。
默认情况下:
-
Docker 会限制容器:
- Linux Capabilities
/dev设备访问- 内核接口
- AppArmor / SELinux
- cgroup 权限
加上:
--privileged
后:
- 容器获得所有 Linux capabilities
- 可以访问所有设备
- 可以执行很多原本禁止的操作
- AppArmor/SELinux 限制会被放宽
- 基本等于“容器内 root ≈ 宿主机 root”
常见用途
1)Docker in Docker
例如:
docker run --privileged docker:dind
容器里再运行 Docker。
2)需要操作内核
例如:
- 挂载文件系统
- 修改 iptables
- 使用 FUSE
- 操作
/sys - 加载内核模块
3)某些 AI / GPU / 驱动环境
某些推理框架需要:
/dev/kfd/dev/dri- RDMA
- InfiniBand
风险
非常大。
如果容器被入侵:
- 可能直接控制宿主机
- 可逃逸
- 可读取宿主机设备
- 可修改网络
生产环境一般:
- 不建议使用
- 除非明确知道原因
更安全替代方案
通常只增加必要 capability:
--cap-add NET_ADMIN
--device /dev/fuse
而不是直接 privileged。
2. --ulimit nproc=65535:65535
--ulimit nproc=65535:65535
作用
限制容器内:
单用户可创建的最大进程数(process number)
对应 Linux:
ulimit -u
格式
soft:hard
这里:
65535:65535
表示:
- soft limit = 65535
- hard limit = 65535
soft/hard 区别
soft
当前生效限制。
普通程序可以降低。
hard
上限。
只有 root 才能提高到 hard。
为什么需要调大?
某些程序:
- Java
- Python 多线程
- OpenBLAS
- TensorFlow
- Gunicorn
- gevent
- JVM
- 大量协程框架
会创建很多:
- 线程
- worker
- fork
Linux 线程本质也是 task/process。
默认可能只有:
1024
4096
容易出现:
pthread_create failed
Resource temporarily unavailable
can't start new thread
你之前遇到的典型错误
你之前 Docker 里:
thread create failed
大概率就和:
- nproc 太小
- OpenBLAS 创建线程失败
有关。
3. --ulimit nofile=65535:65535
--ulimit nofile=65535:65535
作用
限制:
最大可打开文件描述符数量(FD)
对应:
ulimit -n
什么是文件描述符?
Linux 中:
一切皆文件
包括:
- 文件
- socket
- TCP连接
- 管道
- epoll
- device
都占 FD。
默认值通常很低
可能:
1024
4096
高并发程序很容易炸。
常见错误
1)Too many open files
EMFILE
Too many open files
2)数据库连接异常
MySQL / Redis:
- 无法建立新连接
- socket 创建失败
3)Nginx
worker_connections exceed open file resource limit
为什么 AI / Python 容器也要调?
因为:
- HTTP连接
- WebSocket
- 模型 mmap
- 日志文件
- multiprocessing pipe
都会占 FD。
报错信息
Failed to start thread "GC Thread#0" - pthread_create failed (EPERM)
或者
Traceback (most recent call last):
File "/tmp/main.py", line 87, in <module>
File "/tmp/main.py", line 81, in check_dependencies
File "/usr/local/lib/python3.12/site-packages/moviepy/editor.py", line 60, in <module>
from .video.io.sliders import sliders
File "/usr/local/lib/python3.12/site-packages/moviepy/video/io/sliders.py", line 1, in <module>
import matplotlib.pyplot as plt
File "/usr/local/lib/python3.12/site-packages/matplotlib/pyplot.py", line 57, in <module>
import matplotlib.image
File "/usr/local/lib/python3.12/site-packages/matplotlib/image.py", line 25, in <module>
from matplotlib.backend_bases import FigureCanvasBase
File "/usr/local/lib/python3.12/site-packages/matplotlib/backend_bases.py", line 49, in <module>
from matplotlib import (
File "/usr/local/lib/python3.12/site-packages/matplotlib/text.py", line 16, in <module>
from .font_manager import FontProperties
File "/usr/local/lib/python3.12/site-packages/matplotlib/font_manager.py", line 1643, in <module>
fontManager = _load_fontmanager()
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/matplotlib/font_manager.py", line 1637, in _load_fontmanager
fm = FontManager()
^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/matplotlib/font_manager.py", line 1097, in __init__
timer.start()
File "/usr/local/lib/python3.12/threading.py", line 994, in start
_start_new_thread(self._bootstrap, ())
RuntimeError: can't start new thread
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)