我试图在 Fedora 30(12GB RAM)和 Ubuntu 16 Linux 机器(16GB RAM)上分配超过 10K 线程。
我在 10k 线程左右收到这些错误:
- Java:无法创建新的本机线程
- C:资源暂时不可用
遵循 Fedora 机器的一些设置:
$ uname -a
Linux lab21.xxxxx.ix 5.1.11-300.fc30.x86_64 #1 SMP Mon Jun 17 19:33:15 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 47765
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 47765
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
$ cat /proc/sys/kernel/pid_max
32768
$ cat /proc/sys/kernel/threads-max
95530
**$ cat /proc/meminfo (before the stress test)**
MemTotal: 12257732 kB
MemFree: 11424808 kB
MemAvailable: 11772784 kB
Buffers: 74556 kB
Cached: 487680 kB
SwapCached: 0 kB
Active: 424696 kB
Inactive: 224036 kB
Active(anon): 87056 kB
Inactive(anon): 592 kB
Active(file): 337640 kB
Inactive(file): 223444 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 6003828 kB
SwapFree: 6003828 kB
Dirty: 1576 kB
Writeback: 0 kB
AnonPages: 86496 kB
Mapped: 112124 kB
Shmem: 1152 kB
KReclaimable: 45044 kB
Slab: 100440 kB
SReclaimable: 45044 kB
SUnreclaim: 55396 kB
KernelStack: 3600 kB
PageTables: 3784 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 12132692 kB
Committed_AS: 732436 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
Percpu: 7680 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
CmaTotal: 0 kB
CmaFree: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
DirectMap4k: 121280 kB
DirectMap2M: 12427264 kB
**After the stress test**
MemTotal: 12257732 kB
MemFree: 11014248 kB
MemAvailable: 11363328 kB
Buffers: 75096 kB
Cached: 487988 kB
SwapCached: 0 kB
Active: 517840 kB
Inactive: 221644 kB
Active(anon): 176960 kB
Inactive(anon): 600 kB
Active(file): 340880 kB
Inactive(file): 221044 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 6003828 kB
SwapFree: 6003828 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 176428 kB
Mapped: 112408 kB
Shmem: 1160 kB
KReclaimable: 45576 kB
Slab: 208928 kB
SReclaimable: 45576 kB
SUnreclaim: 163352 kB
KernelStack: 171744 kB
PageTables: 46040 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 12132692 kB
Committed_AS: 86824336 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
Percpu: 7872 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
CmaTotal: 0 kB
CmaFree: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
DirectMap4k: 123328 kB
DirectMap2M: 12425216 kB
在比 Fedore 机器多 4 GB 内存的 Ubuntu 机器上,我可以分配不超过 13K。这种差异可能与 Ubuntu 机器的内存更大有关。
有什么提示吗?
答案1
问题是systemd cgroup 限制...
我检查了“/sys/fs/cgroup/pids/user.slice/user-$UID.slice/pids.max”,它是10.813。提高到 15000 并分配线程。
所以 Systemd 也使用 cgroup 来限制资源和线程......
这篇文章是通往真理的道路!
答案2
虽然了解给定系统上的资源限制很有帮助,但在尝试创建如此多的本机线程时,仅此不足以确定错误的根本原因。 e 更有趣的是,您返回的错误pthread_create()
仅告诉您已经超出了资源限制。它没有告诉您的有价值的信息是超出了哪些资源限制:
伊加恩- 资源不足,无法创建另一个线程,或者遇到系统对线程数施加的限制。后一种情况可能以两种方式发生:达到 RLIMIT_NPROC 软资源限制(通过 setrlimit(2) 设置),该限制限制真实用户 ID 的进程数量;或者达到了内核对线程数的系统范围限制 /proc/sys/kernel/threads-max。来源:https://linux.die.net/man/3/pthread_create
不幸的是,这意味着您需要进行繁琐的手动调试来查明哪些资源限制导致了您的问题。
边注: JavaThread
是通过操作系统本机线程实现的,在 Linux 上是 POSIX 线程(pthreads)。与C相同,因此症状相似。
替代
另一种可能适合您并且可以更好地利用您的时间的替代方案是使用轻量级线程(又名绿色线程)。相比之下先发制人本机线程的线程模型(例如 pthreads),其中 Linux 内核负责线程之间的切换,轻量级线程是合作社,这意味着轻量级线程必须定期让位于主线程,以保持多线程执行的感觉。
虽然从表面上看,这似乎是一个较差的模型,但轻量级线程的一大好处是,通常您可以运行约 100K 线程,而对可用资源的影响最小。显然,如果您在每个轻量级线程中打开一个文件,您最终会回到开始的地方,但我建议深入研究轻量级线程,看看它是否对您来说是一个可行的解决方案。