在Linux下,一个进程能够创建的最大线程数是多少?
如果有可能的话,如何修改这个值?
Linux没有单独的进程线程限制,只有一个系统上总进程数的限制(在Linux中,线程本质上就是共享地址空间的进程),您可以像这样查看:
cat /proc/sys/kernel/threads-max
默认值为内存页数/4。您可以像这样增加它:
echo 100000 > /proc/sys/kernel/threads-max
对于单个用户可以创建的进程数(包括线程数),也存在限制,请参阅ulimit/getrlimit
了解这些限制的详细信息。
错误的说法是Linux没有进程线程限制。
Linux间接实现了每个进程的最大线程数限制!!
number of threads = total virtual memory / (stack size*1024*1024)
因此,可以通过增加总虚拟内存或减少堆栈大小来增加每个进程的线程数。但是,太大幅度地缩小堆栈大小可能会导致堆栈溢出而导致代码失败,而最大虚拟内存等于交换空间。
检查您的机器:
总虚拟内存:ulimit -v
(默认为无限制,因此需要增加交换空间以增加此值)
总堆栈大小:ulimit -s
(默认为8Mb)
增加这些值的命令:
ulimit -s newvalue
ulimit -v newvalue
*用要作为限制的新值替换原有值。
参考资料:
http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/
在实际应用中,线程数量的限制通常由堆栈空间决定。如果每个线程分配1MB的堆栈空间(我不确定这是否是Linux上的默认值),那么在32位系统上,如果最后1GB保留给内核,那么大约在创建3000个线程后就会耗尽地址空间。
然而,如果你使用超过几十个线程,你很可能会遇到糟糕的性能问题。迟早会出现过多的上下文切换开销、调度器负担等问题。(创建大量的线程除了占用大量内存外并没有太多作用。但是大量有实际工作任务的线程将争夺可用的CPU时间导致效率下降)
在什么情况下需要考虑线程数量的限制?
在 Linux 上正确地使用 100k 线程:
ulimit -s 256
ulimit -i 120000
echo 120000 > /proc/sys/kernel/threads-max
echo 600000 > /proc/sys/vm/max_map_count
echo 200000 > /proc/sys/kernel/pid_max
./100k-pthread-create-app
2018 年 Thomas 的更新,针对 systemd 系统:
/etc/systemd/logind.conf: UserTasksMax=100000
Linux不使用虚拟内存计算线程的最大值,而是使用系统中安装的物理RAM。
max_threads = totalram_pages / (8 * 8192 / 4096);
http://kavassalis.com/2011/03/linux-and-the-maximum-number-of-processes-threads/
kernel/fork.c
/* The default maximum number of threads is set to a safe
* value: the thread structures can take up at most half
* of memory.
*/
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
每个系统的线程最大值都不同,因为安装的内存大小可能不同。我知道Linux不需要增加虚拟内存,因为在32位上,我们有3 GB的用户空间和1 GB的内核空间,在64位上,我们有128 TB的虚拟内存,这在Solaris上发生。如果要增加虚拟内存,则需要添加交换空间。
要检索它:
cat /proc/sys/kernel/threads-max
设置方法如下:
echo 123456789 | sudo tee -a /proc/sys/kernel/threads-max
123456789 = 线程数
>
)部分:尝试 echo 12345678 | sudo tee -a /proc/sys/kernel/threads-max
。 - dwanderson线程数限制:
$ cat /proc/sys/kernel/threads-max
计算方法:
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
并且: x86_64页面大小(PAGE_SIZE)为4K; 像所有其他架构一样,x86_64为每个活动线程提供内核栈。这些线程栈的大小为THREAD_SIZE(2*PAGE_SIZE);
对于mempages:
cat /proc/zoneinfo | grep spanned | awk '{totalpages=totalpages+$2} END {print totalpages}';
实际上,线程内存堆栈大小的限制与线程数无关 (ulimit -s
).
P.S:我的 RHEL 虚拟机中线程内存堆栈限制为 10M,在 1.5G 内存的情况下,这个虚拟机只能支持 150 个线程?
现在,对于任何查看此内容的人,在systemd系统上(在我的情况下,特别是Ubuntu 16.04),cgroup pids.max参数强制执行另一个限制。
默认情况下,它设置为12,288,并且可以在/etc/systemd/logind.conf中覆盖。
其他建议仍然适用,包括pids_max、threads-max、max_maps_count、ulimits等。
使用 ulimit 命令检查每个线程的堆栈大小,在我的情况下是 Redhat Linux 2.6:
ulimit -a
...
stack size (kbytes, -s) 10240
这可能并不重要。如果您的算法使用固定数量的线程(例如,如果您有4个或8个处理器,则使用4个或8个线程),则性能会更好。您可以使用工作队列、异步IO或类似libevent的东西来实现这一点。