一个进程最多可以创建多少个线程?
前言
话不多说,先来张脑图~
linux 虚拟内存知识回顾
虚拟内存空间长啥样
在 Linux 操作系统中,虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同位数的系统,地址空间的范围也不同。比如最常见的 32 位和 64 位系统,如下所示:
通过这里可以看出:
-
32 位系统的内核空间占用 1G,位于最高处,剩下的 3G 是用户空间;
-
64 位系统的内核空间和用户空间都是 128T,分别占据整个内存空间的最高和最低处,剩下的中间部分是未定义的。
32 位虚拟内存空间
通过这张图你可以看到,用户空间内存,从低到高分别是 6 种不同的内存段:
-
0x0000 0000 到 0x0804 8000 这段虚拟内存地址是一段不可访问的保留区,因为在大多数操作系统中,数值比较小的地址通常被认为不是一个合法的地址,这块小地址是不允许访问的。比如在 C 语言中我们通常会将一些无效的指针设置为 NULL,指向这块不允许访问的地址。
-
代码段,包括二进制可执行代码;
-
数据段,包括已初始化的静态常量和全局变量;
-
BSS 段,包括未初始化的静态变量和全局变量;
-
堆段,包括动态分配的内存,从低地址开始向上增长;
-
堆空间的上边是一段待分配区域,用于扩展堆空间的使用
-
文件映射段,包括动态库、共享内存等,从低地址开始向上增长
-
栈段,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB。当然系统也提供了参数,以便我们自定义大小;
在上面的内存段中,堆和文件映射段的内存是动态分配的。比如说,使用 C 标准库的 malloc() 或者 mmap() ,就可以分别在堆和文件映射段动态分配内存。
64 位虚拟内存空间
我们知道在 32 位机器上,指针的寻址范围为 2^32,所能表达的虚拟内存空间为 4 GB。
那么我们可能会认为在 64 位机器上,指针的寻址范围为 2^64,所能表达的虚拟内存空间为 16 EB 。虚拟内存地址范围为:0x0000 0000 0000 0000 0000 - 0xFFFF FFFF FFFF FFFF 。
事实上在目前的 64 位系统下只使用了 48 位来描述虚拟内存空间,寻址范围为 2^48 ,所能表达的虚拟内存空间为 256TB。
从上图中我们可以看出 64 位系统中的虚拟内存布局和 32 位系统中的虚拟内存布局大体上是差不多的。
创建一个线程需要消耗多大虚拟内存
前面我们也介绍了栈段,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB。当然系统也提供了参数,以便我们自定义大小;
现在我们来验证一下,执行 ulimit -a 这条命令,查看进程创建线程时默认分配的栈空间大小
影响一个进程可创建多少线程的条件
-
进程的虚拟内存空间上限,因为创建一个线程,操作系统需要为其分配一个栈空间,如果线程数量越多,所需的栈空间就要越大,那么虚拟内存就会占用的越多。
-
系统参数限制,虽然 Linux 并没有内核参数来控制单个进程创建的最大线程个数,但是有系统级别的参数来控制整个系统的最大线程个数。
虚拟内存空间上限
32 位系统
在 32 位 Linux 系统里,一个进程的虚拟空间是 4G,内核分走了 1G,用户能用的只有 3G。
创建一个线程需要占用 8M 虚拟内存,总共有 3G 虚拟内存可以使用。于是我们可以算出,最多可以创建差不多 380 个(3G/8M)左右的线程。
如果想使得进程创建上千个线程,那么我们可以调整创建线程时分配的栈空间大小,比如调整为 512k:
[ecs-user@iZ2ze923utbhhwxwgc0pd9Z ~]$ ulimit -s 512
64 位系统
64 位系统意味着用户空间的虚拟内存最大值是 128T,这个数值是很大的,一个线程需占用 8M 栈空间的情况来算,那么理论上可以创建 128T/8M 个线程,也就是 1000 多万个线程,有点魔幻!
所以按 64 位系统的虚拟内存大小,理论上可以创建无数个线程。
系统参数限制
前面学习我们了解到了 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,默认创建线程时分配的栈空间是 8M,那么一个进程最多只能创建 380 个左右的线程。
-
64 位系统,用户态的虚拟空间大到有 128T,理论上不会受虚拟内存大小的限制,而会受系统的参数或性能限制。
相关文章:

一个进程最多可以创建多少个线程?
前言 话不多说,先来张脑图~ linux 虚拟内存知识回顾 虚拟内存空间长啥样 在 Linux 操作系统中,虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同位数的系统,地址空间的范围也不同。比如最常见的 32 位和 64 位系统&am…...

ElasticSearch文档分析
ElasticSearch文档分析 包含下面的过程: 将一块文本分成适合于倒排索引的独立的 词条将这些词条统一化为标准格式以提高它们的“可搜索性”,或者 recall 分析器执行上面的工作。分析器实际上是将三个功能封装到了一个包里: 字符过滤器 首先&a…...

Xilinx FPGA平台DDR3设计详解(一):DDR SDRAM系统框架
DDR SDRAM(双倍速率同步动态随机存储器)是一种内存技术,它可以在时钟信号的上升沿和下降沿都传输数据,从而提高数据传输的速率。DDR SDRAM已经发展了多代,包括DDR、DDR2、DDR3、DDR4和DDR5,每一代都有不同的…...

Spring Data JPA方法名命名规则
最近巩固一下JPA,网上看到这些资料,这里记录巩固一下。 一、Spring Data Jpa方法定义的规则 简单条件查询 简单条件查询:查询某一个实体类或者集合。 按照Spring Data的规范的规定,查询方法以find | read | get开头&…...
【Leetcode Sheet】Weekly Practice 15
Leetcode Test 2586 统计范围内的元音字符串数(11.7) 给你一个下标从 0 开始的字符串数组 words 和两个整数:left 和 right 。 如果字符串以元音字母开头并以元音字母结尾,那么该字符串就是一个 元音字符串 ,其中元音字母是 a、e、i、o、u…...

人力资源社会保障部办公厅关于推行专业技术人员职业资格电子证书的通知
(人社厅发〔2021〕97号) 各省、自治区、直辖市及新疆生产建设兵团人力资源社会保障厅(局),中共海南省委人才发展局,国务院有关部门、直属机构人事部门,有关协会、学会: 为贯彻落实…...

什么是光电耦合器?如何选择型号及种类
光电耦合器(英文缩写为OC)亦称光电隔离器,简称光耦;以光为媒介传输电信号;它对输入、输出电信号有良好的隔离作用,是目前种类最多、用途最广的光电器件之一;所以,它在各种电路中得到广泛的应用。 光耦合器…...

hive里因为列名用了关键字导致建表失败
代码 现象 ParseException line 6:4 cannot recognize input near percent String COMMENT in column name or primary key or foreign key 23/11/13 11:52:57 ERROR org.apache.hadoop.hive.ql.Driver: FAILED: ParseException line 6:4 cannot recognize input near percent …...
MySQL 报错 incorrect datetime value ‘0000-00-00 00:00:00‘ for column
使用navicat导入数据时报错: MySQL 报错 incorrect datetime value ‘0000-00-00 00:00:00’ for column 这是因为当前的MySQL不支持datetime为0的情况。 MySQL报incorrect datetime value ‘0000-00-00 00:00:00’ for column错误原因,是由于在MySQL5.7…...
Jira Data Center(非集群)升级操作
一、升级准备 Jira 管理界面执行升级检查下载升级包,使用原操作方式相同的方式安装。我这里原来的版本是通过./atlassian-jira-software-9.11.2-x64.bin安装的,接下来下载atlassian-jira-software-9.11.3-x64.bin的安装文件停止 Jira,bin/st…...

Spring IOC - BeanDefinition解析
1. BeanDefinition的属性 BeanDefinition作为接口定义了属性的get、set方法。这些属性基本定义在其直接实现类AbstractBeanDefinition中,各属性的含义如下表所示: 类型 名称 含义 常量 SCOPE_DEFAULT 默认作用域:单例模式 AUT…...

ds前后台博客系统
源码私信或者公众号java大师获取 博客简介:本博客采用Spring Boot LayUI做为基础,进行的博客系统开发,与bootvue相比,更为适合开发简单的系统,并且更容易上手,简单!高效!更易上手&a…...
算法leetcode|88. 合并两个有序数组(rust重拳出击)
文章目录 88. 合并两个有序数组:样例 1:样例 2:样例 3:提示: 分析:题解:rust:go:c:python:java: 88. 合并两个有序数组: …...

GoLong的学习之路,进阶,语法之并发(并发错误处理)补充并发三部曲
这篇文章主要讲的是如何去处理并发的错误。 在Go语言中十分便捷地开启goroutine去并发地执行任务,但是如何有效的处理并发过程中的错误则是一个很棘手的问题。 文章目录 recovererrgroup recover 哦对,似乎没写错误处理的文章。后面补上。 首先&…...

猪酒店房价采集
<?php // 设置代理 $proxy_host jshk.com.cn;// 创建一个cURL资源 $ch curl_init();// 设置代理 curl_setopt($ch, CURLOPT_PROXY, $proxy_host.:.$proxy_port);// 连接URL curl_setopt($ch, CURLOPT_URL, "http://www.zujia.com/");// 发送请求并获取HTML文档…...

Java基础知识第四讲:Java 基础 - 深入理解泛型机制
Java 基础 - 深入理解泛型机制 背景:Java泛型这个特性是从JDK 1.5才开始加入的,为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,即Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”࿰…...

ceph-deploy bclinux aarch64 ceph 14.2.10【2】vdbench rbd 块设备rbd 测试失败
上篇 ceph-deploy bclinux aarch64 ceph 14.2.10-CSDN博客 安装vdbench 下载vdbench 下载页面 Vdbench Downloads (oracle.com) 包下载 需要账号登录,在弹出层点击同意才能继续下载 用户手册 https://download.oracle.com/otn/utilities_drivers/vdbench/vdb…...
split_train_val
# coding:utf-8 import os import random import argparse parser argparse.ArgumentParser() # xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下 parser.add_argument(--xml_path, defaultdata_door_white/xml/train, typestr, helpinput xm…...

Linux Mint 21.3 将搭载 Cinnamon 6.0 和实验性 Wayland 支持
导读Wayland 会话可能在 Linux Mint 23 系列中成为默认选项,预计将在 2026 年实现。 Linux Mint 项目今天在他们的每月新闻通讯中 宣布,他们已经开始着手在未来的 Linux Mint 发行版中实施 Wayland 会话,最初将在 Linux Mint 21.3 中提供。 …...

名师助阵龙讯旷腾PWmat+半导体缺陷培训暨半导体缺陷计算大赛
半导体缺陷计算大赛 选拔赛截止日期:11月23日 参与杭州线下培训直接跳过选拔赛 大赛亮点 线上免费培训、线下限时领取免费名额 线下杭州培训可直通决赛,跳过选拔赛 线上培训有3次机会参与考试进入决赛 已购/未购用户均可参加、无身份限定 使用Mc…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)
目录 🔍 若用递归计算每一项,会发生什么? Horners Rule(霍纳法则) 第一步:我们从最原始的泰勒公式出发 第二步:从形式上重新观察展开式 🌟 第三步:引出霍纳法则&…...
boost::filesystem::path文件路径使用详解和示例
boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类,封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解,包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...

职坐标物联网全栈开发全流程解析
物联网全栈开发涵盖从物理设备到上层应用的完整技术链路,其核心流程可归纳为四大模块:感知层数据采集、网络层协议交互、平台层资源管理及应用层功能实现。每个模块的技术选型与实现方式直接影响系统性能与扩展性,例如传感器选型需平衡精度与…...