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

时间:2008-12-05 15:38:07

标签: linux multithreading

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

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

16 个答案:

答案 0 :(得分:218)

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

cat /proc/sys/kernel/threads-max

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

echo 100000 > /proc/sys/kernel/threads-max

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

答案 1 :(得分:63)

这是错误的说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/

答案 2 :(得分:42)

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

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

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

答案 3 :(得分:20)

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更新系统系统:

/etc/systemd/logind.conf: UserTasksMax=100000

答案 4 :(得分:13)

@dragosrsupercool

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

 max_threads = totalram_pages / (8 * 8192 / 4096);

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);

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

答案 5 :(得分:11)

要检索它:

cat /proc/sys/kernel/threads-max

设置它:

echo 123456789 > /proc/sys/kernel/threads-max

123456789 =线程数

答案 6 :(得分:7)

线程数限制:

$ 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)大;

for mempages:

cat /proc/zoneinfo | grep spanned | awk '{totalpages=totalpages+$2} END {print totalpages}';

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

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

答案 7 :(得分:4)

这可能不重要。设计算法以获得更好的性能以使用固定数量的线程(例如,如果您有4个或8个处理器,则为4或8)。您可以使用工作队列,异步IO或类似libevent的方法来完成此操作。

答案 8 :(得分:3)

使用nbio 非阻塞i / o 库或其他什么,如果你需要更多线程来进行阻止

的I / O调用

答案 9 :(得分:3)

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

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

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

答案 10 :(得分:3)

使用ulimit检查每个线程的堆栈大小,在我的例子中是Redhat Linux 2.6:

    ulimit -a
...
    stack size              (kbytes, -s) 10240

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

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

答案 11 :(得分:2)

取决于你的系统,只需编写一个示例程序[通过循环创建进程]并使用ps axo pid,ppid,rss,vsz,nlwp,cmd进行检查。当它不能再创建线程时检查nlwp计数[nlwp是数字线程]瞧,你得到了你的傻瓜证明答案,而不是通过书籍

答案 12 :(得分:1)

我认为我们错过了另一个限制,它也会阻止新线程的创建,这是 kernel.pid_max 限制。

root@myhost:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.7 LTS
Release:    16.04
Codename:   xenial
root@myhost:~# uname -a
Linux myhost 4.4.0-190-generic #220-Ubuntu SMP Fri Aug 28 23:02:15 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

我发现至少在我的系统中,这个阈值 kernel.pid_max 是 32768。当我启动任何简单的 JVM 进程时,它报告如下错误:

java/jstack/jstat ...
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create GC thread. Out of system resources.
# An error report file with more information is saved as:
# /root/hs_err_pid1390.log

检查内存,充足。

root@lascorehadoop-15a32:~# free -mh
              total        used        free      shared  buff/cache   available
Mem:           125G         11G         41G        1.2G         72G        111G
Swap:            0B          0B          0B

检查系统线程:

~# ps -eLf|wc -l
31506

但是我通过ulimit检查了系统限制:

root@myhost:~# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 515471
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 98000
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) 515471
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

从 ulimit 输出中,我们可以看到当前线程数远小于最大用户进程限制。

实际上,达到的限制是kernel.pid_max

很容易检查和调整它: https://www.cyberciti.biz/tips/howto-linux-increase-pid-limits.html

答案 13 :(得分:0)

我们可以看到linux中以下文件中定义的最大线程数

cat / proc / sys / kernel / threads-max

(OR)

sysctl -a | grep threads-max

答案 14 :(得分:0)

要永久设置,

vim /etc/sysctl.conf

并添加

kernel.threads-max = "value"

答案 15 :(得分:0)

是的,要增加线程数,您需要增加虚拟内存或减小堆栈大小。在Raspberry Pi中,我没有找到增加虚拟内存的方法,如果将堆栈大小从默认的8MB减小到1MB,则每个进程可能获得1000个以上的线程,但是使用“ ulimit -s”命令减小了堆栈大小。使这适用于所有线程。因此,我的解决方案是使用“ pthread_t”实例“线程类”,因为pthread_t允许我设置每个线程的堆栈大小。最后,我可以在Raspberry Pi中为每个进程归档1000多个线程,每个线程具有1MB的堆栈。