windows 最大支持线程数

摘要:
Windows操作系统中允许的最大线程数。默认情况下,应该为线程堆栈保留1M的内存空间,而进程只能使用2G的内存空间。理论上,一个进程最多可以打开2048个线程,但当然,内存不能用作线程堆栈。因此,实际数字应小于此值。您还可以在连接时将默认堆栈大小更改为较小的大小,以便可以打开更多线程。如果默认堆栈的大小更改为512K,理论上最多可以打开4096个线程。即使物理内存
WINDOWS操作系统中可以允许最大的线程数

默认情况下,一个线程的栈要预留1M的内存空间 
而一个进程中可用的内存空间只有2G,所以理论上一个进程中最多可以开2048个线程 
但是内存当然不可能完全拿来作线程的栈,所以实际数目要比这个值要小。 
你也可以通过连接时修改默认栈大小,将其改的比较小,这样就可以多开一些线程。 
如将默认栈的大小改成512K,这样理论上最多就可以开4096个线程。 

即使物理内存再大,一个进程中可以起的线程总要受到2GB这个内存空间的限制。 
比方说你的机器装了64GB物理内存,但每个进程的内存空间还是4GB,其中用户态可用的还是2GB。 


如果是同一台机器内的话,能起多少线程也是受内存限制的。每个线程对象都要站用非页面内存,而非页面内存也是有限的,当非页面内存被耗尽时,也就无法创建线程了。 

如果物理内存非常大,同一台机器内可以跑的线程数目的限制值会越来越大。  

在Windows下写个程序,一个进程Fork出2000个左右线程就会异常退出了,为什么?

这个问题的产生是因为windows32位系统,一个进程所能使用的最大虚拟内存为2G,而一个线程的默认线程栈StackSize为1024K(1M),这样当线程数量逼近2000时,2000*1024K=2G(大约),内存资源就相当于耗尽。

MSDN原文:

“The number of threads a process can create is limited by the available virtual memory. By default, every thread has one megabyte of stack space. Therefore, you can create at most 2,028 threads. If you reduce the default stack size, you can create more threads.However, your application will have better performance if you create one thread per processor and build queues of requests for which the application maintains the context information. A thread would process all requests in a queue before processing requests in the next queue.”

如何突破2000个限制?

可以通过修改CreateThread参数来缩小线程栈StackSize,例如

#define   MAX_THREADS   50000
 
DWORD   WINAPI   ThreadProc(   LPVOID   lpParam   ){
while(1){
Sleep(100000);
}
return   0;
}
 
int   main()   {
DWORD   dwThreadId[MAX_THREADS];
HANDLE   hThread[MAX_THREADS];
 
for(int   i   =   0;   i   <   MAX_THREADS;   ++i)
{
hThread[i]  = CreateThread(0,  64, ThreadProc, 0, STACK_SIZE_PARAM_IS_A_RESERVATION,   &dwThreadId[i]);
 
if(0   ==   hThread[i])
{
DWORD   e   =   GetLastError();
printf("%d
",e);
break;
}
}
ThreadProc(0);
}

  

服务器端程序设计

如果你的服务器端程序设计成:来一个client连接请求则创建一个线程,那么就会存在2000个限制(在硬件内存和CPU个数一定的情况下)。建议如下:

The "one thread per client" model is well-known not to scale beyond a dozen clients or so. If you're going to be handling more than that many clients simultaneously, you should move to a model where instead of dedicating a thread to a client, you instead allocate an object. (Someday I'll muse on the duality between threads and objects.) Windows provides I/O completion ports and a thread pool to help you convert from a thread-based model to a work-item-based model.

1. Serve many clients with each thread, and use nonblocking I/O and level-triggeredreadiness notification
2. Serve many clients with each thread, and use nonblocking I/O and readiness change notification
3. Serve many clients with each server thread, and use asynchronous I/O

免责声明:文章转载自《windows 最大支持线程数》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CPU缓存L1/L2/L3工作原理Hyper-V初涉_早期Windows安装虚拟硬件驱动下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C#线程锁(上)

本篇从Monitor,Mutex,ManualResetEvent,AutoResetEvent,WaitHandler的类关系图开始,希 望通过本篇的介绍能对常见的线程同步方法有一个整体的认识,而对每种方式的使用细节,适用场合不会过多解释。让我们来看看这几个类的关系图:         1.lock关键字       lock是C#关键词,它将语句块标记...

JVM 源码分析(四):深入理解 park / unpark

前言 Parker 源码调试与分析 park/unpark 原理总结 补充:jstack 命令和 kill 命令 前言 熟悉 Java 并发包的人一定对 LockSupport 的 park/unpark 方法不会感到陌生,它是 Lock(AQS)的基石,给 Lock(AQS)提供了挂起/恢复当前线程的能力。 LockSupport 的 par...

Xenu Link Sleuth 简单好用的链接测试工具 使用说明

 XenuLink Sleuth 名词介绍       “Xenu链接检测侦探”是被广泛使用的死链接检测工具。可以检测到网页中的普通链接、图片、框架、插件、背景、样式表、脚本和java程序中的链接。 那么神马时候出现死链接: 动态链接在数据库不再支持的条件下,变成死链接。 某个文件或网页移动了位置,导致指向它的链接变成死链接。 网页内容更新并换成其他的链...

Android Looper详解

在Android下面也有多线程的概念,在C/C++中,子线程可以是一个函数, 一般都是一个带有循环的函数,来处理某些数据,优先线程只是一个复杂的运算过程,所以可能不需要while循环,运算完成,函数结束,线程就销毁。对于那 些需要控制的线程,一般我们都是和互斥锁相互关联,从而来控制线程的进度,一般我们创建子线程,一种线程是很常见的,那就是带有消息循环的线程...

WinForm 子线程修改主线程(UI线程)

原文http://www.cnblogs.com/SkySoot/archive/2012/03/14/2396552.html 我们先来看一段运行时会抛出 InvalidOperationException 异常的代码段: 1 public partial class TestThread : Form 2 { 3 public Test...

二、Apache MPM三种工作模式

一、Apache即现阶段比较流行的Web服务,是一个多模块化的Web服务,使用简单,速度快,稳定性好,可以做负载均衡及代理服务器来使用。 二、Apache有三种工作模式分别是 prefork、work、even Apache prefork模型 1、prefork介绍 prefork模型,有一个主控制进程,然后生成多个子进程,使用select模型,最...