Linux中每个进程的最大线程数?

228 linux multithreading

Linux下进程可以创建的最大线程数是多少?

如何(如果可能)可以修改此值?

Rob*_*ble 231

Linux没有每个进程限制的单独线程,只是对系统上进程总数的限制(线程本质上只是在Linux上具有共享地址空间的进程),您可以像这样查看:

cat /proc/sys/kernel/threads-max
Run Code Online (Sandbox Code Playgroud)

默认值是内存页数/ 4.你可以增加这个:

echo 100000 > /proc/sys/kernel/threads-max
Run Code Online (Sandbox Code Playgroud)

单个用户可能创建的进程数(以及线程数)也有限制,ulimit/getrlimit有关这些限制的详细信息,请参阅.

  • @dragosrsupercool使用总ram计算最大线程,没有虚拟内存 (4认同)
  • / proc/sys/vm/max_map_count中的限制也可能限制线程数.如果你点击它会增加这个限制应该是安全的. (3认同)
  • 每个线程的堆栈大小(系统上的默认值)更有可能成为限制。减少每个线程堆栈大小是增加线程总数的一种方法(尽管这很少是一个好主意)。 (2认同)

cod*_*ark 64

这是错误的说LINUX没有每个进程限制的单独线程.

Linux间接实现每个进程的最大线程数!!

number of threads = total virtual memory / (stack size*1024*1024)
Run Code Online (Sandbox Code Playgroud)

因此,可以通过增加总虚拟内存或减少堆栈大小来增加每个进程的线程数.但是,过多地减少堆栈大小会导致代码失败,因为堆栈溢出,而最大虚拟内存等于交换内存.

检查你的机器:

总虚拟内存:( ulimit -v默认为无限制,因此您需要增加交换内存以增加此值)

总堆栈大小:( ulimit -s默认为8Mb)

用于增加这些值的命令:

ulimit -s newvalue

ulimit -v newvalue
Run Code Online (Sandbox Code Playgroud)

*将新值替换为您想要作为限制的值.

参考文献:

http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/

  • 除了3个小细节:1.Linux没有这样做,堆栈的存在以及内存和地址空间有限大小这一事实与它无关.2.创建它时必须指定一个线程的堆栈,这与`ulimit -s`无关.创建与可能的线程ID一样多的线程是非常可能的(不合理,但可能).在64位Linux下,创建比线程ID更多的线程更容易"可能"(当然这是不可能的,但就堆栈而言,它是).3.堆栈保留,提交和VM是不同的东西,尤其是OC. (11认同)

jal*_*alf 43

实际上,限制通常由堆栈空间决定.如果每个线程获得1MB堆栈(我不记得这是否是Linux上的默认值),那么32位系统将在3000个线程之后耗尽地址空间(假设最后一个gb保留给内核) .

但是,如果使用超过几十个线程,您很可能会遇到糟糕的性能.迟早,您会得到太多的上下文切换开销,调度程序中的开销太多,等等.(创建大量线程只会占用大量内存.但是很多线程需要做实际工作,因为他们正在争夺可用的CPU时间,这会减慢你的速度)

在这个限制甚至相关的情况下你在做什么?

  • 性能取决于线程正在做什么.如果他们没有做太多事情,那么你可以远远高于几十个,因此更少的上下文切换. (13认同)
  • 堆栈的每个线程1MB非常高,许多程序不需要在这么多的堆栈空间附近.性能将基于*runnable*进程的数量,而不是存在的线程数.我现在有一台机器运行1200+线程,负载为0.40. (3认同)
  • linux x86中默认的线程堆栈大小是2 Mb (2认同)
  • 由于“超过几十个线程”而投反对票。要么增加它,要么移除 ir,要么用源支持它。 (2认同)

Vla*_*kov 24

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
Run Code Online (Sandbox Code Playgroud)

@Thomas在系统系统上更新2018年:

/etc/systemd/logind.conf: UserTasksMax=100000
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,它最终让我突破了32k的Java线程数. (4认同)
  • @VladimirKunschikov感谢朋友,您的解决方案确实有效,并且感谢Thomas添加了该额外的行,我可以确定它超出该行将无法使用。 (2认同)

c4f*_*t0r 13

@dragosrsupercool

Linux不使用虚拟内存来计算线程的最大值,而是使用系统上安装的物理ram

 max_threads = totalram_pages / (8 * 8192 / 4096);
Run Code Online (Sandbox Code Playgroud)

http://kavassalis.com/2011/03/linux-and-the-maximum-number-of-processes-threads/

核心/ 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);
Run Code Online (Sandbox Code Playgroud)

因此,每个系统之间的线程最大值不同,因为安装的ram可以来自不同的大小,我知道Linux不需要增加虚拟内存,因为在32位上我们有3 GB的用户空间和1 GB的内核,在64位上我们得到了128 TB的虚拟内存,这种情况发生在Solaris上,如果你想增加你需要添加交换空间的虚拟内存.


Vin*_*ghe 11

要检索它:

cat /proc/sys/kernel/threads-max
Run Code Online (Sandbox Code Playgroud)

设置它:

echo 123456789 > /proc/sys/kernel/threads-max
Run Code Online (Sandbox Code Playgroud)

123456789 =线程数


小智 9

线程数限制:

$ cat /proc/sys/kernel/threads-max 
Run Code Online (Sandbox Code Playgroud)

如何计算:

max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
Run Code Online (Sandbox Code Playgroud)

和: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}';
Run Code Online (Sandbox Code Playgroud)

实际上这个数字与线程内存堆栈大小(ulimit -s)的限制无关.

PS:我的rhel VM中线程内存堆栈限制为10M,对于1.5G内存,这个VM只能承受150个线程?


Tre*_*oyd 6

对于现在正在查看此内容的任何人,在 systemd 系统(在我的情况下,特别是 Ubuntu 16.04)上,还有另一个由 cgroup pids.max 参数强制执行的限制。

默认设置为 12,288,可以在 /etc/systemd/logind.conf 中覆盖

其他建议仍然适用,包括 pids_max、threads-max、max_maps_count、ulimits 等。


Axe*_*ehl 5

使用 ulimit 检查每个线程的堆栈大小,在我的情况下是 Redhat Linux 2.6:

    ulimit -a
...
    stack size              (kbytes, -s) 10240
Run Code Online (Sandbox Code Playgroud)

您的每个线程都将获得分配给它的堆栈的内存量 (10MB)。使用 32 位程序和 4GB 的最大地址空间,最多只有 4096MB / 10MB = 409 个线程!!!减去程序代码,减去堆空间可能会导致观察到的最大值。300 个线程。

您应该能够通过在 64 位上编译和运行或设置 ulimit -s 8192 甚至 ulimit -s 4096 来提高这一点。但如果这是可取的,则是另一个讨论......