翻译《The Old New Thing》- Does Windows have a limit of 2000 threads per process?

devtools/2024/10/18 14:23:39/

Does Windows have a limit of 2000 threads per process? - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20050729-14/?p=34773

Raymond Chen 2005年07月29日


Windows 是否有一个每个进程2000线程的限制?

简要

        文章解释了在 Windows 程序中创建超过 2000 个线程的限制并非由操作系统本身设定,而是由于每个线程需要分配栈空间,这会消耗大量的地址空间。通过减少每个线程的栈大小,可以增加线程的数量,但这种做法并不推荐,因为它会导致性能下降和潜在的稳定性问题。作者建议使用 I/O 完成端口和线程池等机制来更有效地处理大量并发任务。

 

正文

        经常有人问为什么他们不能在一个进程中创建超过大约2000个线程。原因并不是 Windows 本身有任何特定的限制。相反,是程序员没有考虑到每个线程使用的地址空间量。

        一个线程由一些在内核模式下的内存(内核栈和对象管理)、一些在用户模式下的内存(线程环境块、线程局部存储等)以及它的栈组成。(或者如果你在 Itanium 系统上,是栈们。)

        通常,限制因素是栈的大小。

#include <cstdio>
#include <windows.h>DWORD CALLBACK ThreadProc(void*) {Sleep(INFINITE);return 0;
}int __cdecl main(int argc, const char* argv[]) {int i;for (i = 0; i < 100000; i++) {DWORD id;HANDLE h = CreateThread(NULL, 0, ThreadProc, NULL, 0, &id);if (!h) break;CloseHandle(h);}printf("Created %d threads\n", i);return 0;
}

        这个程序通常会打印出大约2000个线程的数量。

        为什么在大约2000个线程时失败?

        因为链接器分配的默认栈大小是 1MB,2000 个栈乘以每个栈 1MB 等于大约 2GB,这是用户模式程序可用的地址空间总量。

        你可以通过减少栈大小来尝试将更多的线程压缩到你的进程中,这可以通过调整链接器选项或手动覆盖传递给 CreateThread 函数的栈大小来实现,如 MSDN 所述。

HANDLE h = CreateThread(NULL, 4096, ThreadProc, NULL,STACK_SIZE_PARAM_IS_A_RESERVATION, &id);

        通过这个改变,我能够勉强创建大约 13000 个线程。虽然这当然比 2000 个好,但离天真的期望 500000 个线程还有差距。(在 2GB 的地址空间中,一个线程使用 4KB 的栈。)但你忘记了其他的开销。地址空间分配粒度是 64KB,因此即使只使用了 4KB,每个线程的栈也占用 64KB 的地址空间。当然,你并不是可以自由地使用全部 2GB 的地址空间;还有系统 DLL 和其他东西占用了它。

        但每当有人问,“一个进程可以创建的最大线程数是多少?”时,真正提出的问题其实是,“你为什么创建这么多线程,甚至于成了一个问题?”

        “每个客户端一个线程”的模型众所周知,无法扩展到十几个客户端左右。如果你要同时处理这么多客户端,你应该转移到一个模型,不是为每个客户端分配一个线程,而是分配一个对象。(总有一天我会思考线程和对象之间的对偶性。)Windows 提供了 I/O 完成端口和线程池,帮助你从基于线程的模型转换为基于工作项的模型。

        请注意,纤程在这里并没有太大帮助,因为纤程有一个栈,而且几乎总是栈所需的地址空间是限制因素。


http://www.ppmy.cn/devtools/36367.html

相关文章

LeetCode 226.翻转二叉树

题目描述 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a;root [2,1,3] 输出&#xff1a;[2,3,1]示例…

VBA快速删除Excel工作表

Excel处理数据时,经常需要删除部分工作表,像这样 工作中一个工作薄中十几张甚至几十张工作表是常有的事,手动一张张去删,费时费力,VBA代码可以帮你快速搞定,这就需要非常简单的代码 。 1、如果只留下一张名为“Sheet1”的工作表,其余的全删除,代码如下: For Each She…

fero - yolo - mamba:基于选择性状态空间的面部表情检测与分类

fero - yolo - mamba:基于选择性状态空间的面部表情检测与分类 摘要IntroductionRelated work FER-YOLO-Mamba: Facial Expression Detection and Classification Based on Selective State Space 摘要 面部表情识别&#xff08;FER&#xff09;在理解人类情绪线索方面起着关键…

免备案香港主机会影响网站收录?

免备案香港主机会影响网站收录?前几天遇到一个做电子商务的朋友说到这个使用免备案香港主机的完整会不会影响网站的收录问题&#xff0c;这个问题也是站长关注较多的问题之一。小编查阅了百度官方规则说明&#xff0c;应该属于比较全面的。下面小编给大家介绍一下使用免备案香…

每日OJ题_贪心算法三③_力扣45. 跳跃游戏 II(dp解法+贪心解法)

目录 力扣45. 跳跃游戏 II 解析代码1_动态规划 解析代码2_贪心 力扣45. 跳跃游戏 II 45. 跳跃游戏 II 难度 中等 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 num…

Autodesk AutoCAD 2025 for Mac:强大的二维三维绘图工具

Autodesk AutoCAD 2025 for Mac是一款专为Mac用户打造的计算机辅助设计软件&#xff0c;它在继承了AutoCAD系列软件的优秀传统的基础上&#xff0c;针对Mac系统进行了全面优化&#xff0c;为用户提供了更出色的绘图和设计体验。 这款软件不仅支持用户创建和编辑复杂的二维几何图…

充电宝买哪个牌子?四款性能超强充电宝牌子推荐!速来码住!

在快节奏的现代生活中&#xff0c;手机已经成为了我们最亲密的伙伴。无论是工作、学习还是娱乐&#xff0c;手机都扮演着至关重要的角色。然而&#xff0c;手机电量的问题总是让人头疼。特别是在外出旅行时&#xff0c;手机电量耗尽更是让人倍感焦虑。为了解决这个问题&#xf…

Spring IoCDI(3)—DI详解

目录 一、属性注入 二、构造方法注入 小结&#xff1a;构造函数的注入 三、Setter注入 四、三种注入的优缺点分析&#xff08;面试题&#xff09; 1、属性注入 优点&#xff1a; 缺点&#xff1a; 2、构造方法注入&#xff08;Spring4.X推荐&#xff09; 优点&#x…