you are better than you think

sys.kernel.threads-max默认值

· by thur · Read in about 1 min · (108 Words)
linux kernel max threads

背景

物理机时代,业务根据/proc/sys/kernel/threads-max设置线程池大小。容器(特指docker)该值仍然获取的是物理机上的信息,而容器规格一般比物理机小,再根据这个值获取信息设置容器内线程数就不准确了。物理机上这个值受哪些资源影响,因此有了这篇文章。

梳理

内核版本4.18 线程数限制为[20,0x3fffffff]

代码中设置threads的计算公式

threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE, (u64) THREAD_SIZE * 8UL);

threads < min时, 取MIN_THREADS; 当threads > max时, 取MAX_THREADS; 否则,取threads值。其中 max_threads_suggested值传入的就是MAX_THREADS

totalram_pages*PAGE_SIZE ≈ totalram ,代入公式

threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE, (u64) THREAD_SIZE * 8UL);

得到

threads ≈ div64_u64(totalram, THREAD_SIZE*8)

上面totalram_pages*PAGE_SIZE ≈ totalram 说近似相等,是因为物理内存并不是全归内核管理,还有一部分内存是处于内核代码段/dtb(device tree blob)及保留内存+系统共用内存部分

根据configs/kernel-4.18.0-x86_64.config得知 # CONFIG_KASAN is not set

所以KASAN_STACK_ORDER = 0

代入计算,得到

threads ≈ div64_u64(totalram,(PAGE_SIZE << THREAD_SIZE_ORDER)*8)
=>
threads ≈ div64_u64(totalram,(PAGE_SIZE << 2)*8) 

代入计算

threads ≈ div64_u64(totalram, 16KB*8)

验证

预估值 free -k | grep Mem | awk '{printf("%d\n", $2/128)}'cat /proc/meminfo |grep MemTotal | awk '{printf("%d\n", $2/128)}'

实际值 cat /proc/sys/kernel/threads-max

结论

max-threads 约为内存大小(单位KB) ➗ 128

版权所有,转载请注明作者和出处

Comments