5.6 一个进程最多可以创建多少个线程?
这个问题跟两个东西有关系:
进程的虚拟内存空间上限,因为创建一个线程,操作系统需要为其分配一个栈空间,如果线程数量越多,所需的栈空间就要越大,那么虚拟内存就会占用的越多。
- 我们可以执行 ulimit -a 这条命令,查看进程创建线程时默认分配的栈空间大小
系统参数限制,虽然 Linux 并没有内核参数来控制单个进程创建的最大线程个数,但是有系统级别的参数来控制整个系统的最大线程个数。
在 32 位 Linux 系统里,一个进程的虚拟空间是 4G,内核分走了 1G,留给用户用的只有 3G。
那么假设创建一个线程需要占用 10M 虚拟内存,总共有 3G 虚拟内存可以使用。于是我们可以算出,最多可以创建差不多 300 个(3G/10M)左右的线程。
64 位系统;
- 2G 物理内存;
- 单核 CPU。
64 位系统意味着用户空间的虚拟内存最大值是 128T,这个数值是很大的,如果按创建一个线程需占用 10M 栈空间的情况来算,那么理论上可以创建 128T/10M 个线程,也就是 1000 多万个线程,有点魔幻!
所以按 64 位系统的虚拟内存大小,理论上可以创建无数个线程。
事实上,肯定创建不了那么多线程,除了虚拟内存的限制,还有系统的限制。
比如下面这三个内核参数的大小,都会影响创建线程的上限:
- /proc/sys/kernel/threads-max,表示系统支持的最大线程数,默认值是
14553; - /proc/sys/kernel/pid_max,表示系统全局的 PID 号数值的限制,每一个进程或线程都有 ID,ID 的值超过这个数,进程或线程就会创建失败,默认值是
32768; - /proc/sys/vm/max_map_count,表示限制一个进程可以拥有的 VMA(虚拟内存区域) 的数量,具体什么意思我也没搞清楚,反正如果它的值很小,也会导致创建线程失败,默认值是
65530。 - 想要创建更多的线程数目,需要调大前面三个值
好了,简单总结下:
- 32 位系统,用户态的虚拟空间只有 3G,如果创建线程时分配的栈空间是 10M,那么一个进程最多只能创建 300 个左右的线程。
- 64 位系统,用户态的虚拟空间大到有 128T,理论上不会受虚拟内存大小的限制(没有实际使用,不会实际映射),而会受系统的参数或性能限制。
