默认情况下,一个线程的栈要预留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\r\n",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 changenotification
3. Serve many clients with each server thread, and use asynchronous I/O

http://www.cnblogs.com/lancidie/archive/2011/12/15/2289337.html

WINDOWS操作系统中可以允许最大的线程数(线程栈预留1M空间)(56篇Windows博客值得一看)的更多相关文章

  1. windows操作系统中安装、启动和卸载memcached

    今天总结一下如何在Windows操作系统中安装.启动和卸载memcached:下载地址: http://download.csdn.net/download/wangshuxuncom/8249501 ...

  2. 在Windows操作系统中,如何终止占有的8080端口的tomcat进程

    在Windows操作系统中,我们在启动一个tomcat服务器时,经常会发现8080端口已经被占用的错误,而我们又不知道如何停止这个tomcat服务器. 本文将通过命令来强行终止这个已经运行的tomca ...

  3. CVE-2019-0797漏洞:Windows操作系统中的新零日在攻击中被利用

    https://securelist.com/cve-2019-0797-zero-day-vulnerability/89885/ 前言 在2019年2月,卡巴实验室的自动漏洞防护(AEP)系统检测 ...

  4. Ant—怎样Windows操作系统中搭建Apache Ant环境

    介绍一下怎样在Windows操作系统中搭建Apache Ant环境: 一.下载Apache Ant压缩文件:http://download.csdn.net/detail/wangshuxuncom/ ...

  5. 在windows操作系统中,查询端口占用和清除端口占用的程序

    一.在windows操作系统中,查询端口占用和清除端口占用的程序 提升权限后用:netstat -b或用 1.查询端口占用的进程ID 点击"开始"-->"运行&qu ...

  6. Git—怎样Windows操作系统中安装Git

    介绍一下怎样在Windows操作系统中安装Git: 一.下载Git安装压缩文件:http://download.csdn.net/detail/wangshuxuncom/8035045 二.解压该压 ...

  7. [转]在 Windows 操作系统中的已知安全标识符(Sid security identifiers)

    安全标识符 (SID) 是用于标识安全主体或安全组在 Windows 操作系统中的可变长度的唯一值.常用 Sid 的 Sid 标识普通用户的一组或通用组.跨所有操作系统,它们的值保持不变. 此信息可用 ...

  8. 在Windows操作系统中安装MongoDB

    如何在Windows操作系统中安装MongoDB: https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/ 启动Mon ...

  9. WINDOWS操作系统中可以允许最大的线程数

      默认情况下,一个线程的栈要预留1M的内存空间 而一个进程中可用的内存空间只有2G,所以理论上一个进程中最多可以开2048个线程 但是内存当然不可能完全拿来作线程的栈,所以实际数目要比这个值要小.  ...

随机推荐

  1. framework层和native层实现联网控制(iptable方式)

    最近工作中,需要开发一个功能----联网控制,这个功能其实用过root的安卓机应该都知道,禁止某个应用连接移动网络或者wifi. root后,通过su去执行iptable的命令就可以根据uid去控制应 ...

  2. Deep Learning(深度学习)学习笔记整理系列之(八)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  3. asp.net word内容读取到页面

    1.添加Microsoft.Vbe.Interop.dll引用. 2.以下方法可以简单的读取到word文档文字内容,不包括图片.格式等. private string ReadWordFile(str ...

  4. 思考----拒绝单纯copy

    工作4个多月以来感触最深的是: 做事情的时候遇到不会的可以上网查或者问别人,但是获取到的知识不能只是单纯的copy过来使用达到要求就ok, 更重要的是事后等有空了一定要仔细研究学习,使知识网络完整,这 ...

  5. Farpoint Spread 常用事件

    1 // 单元格编辑结束,焦点离开或者按回车键时 比如:你要判断当前单元格输入内容是否合法.private void fpSpread1_EditModeOff(object sender, Syst ...

  6. BZOJ 1901: Zju2112 Dynamic Rankings( 树状数组套主席树 )

    裸的带修改主席树.. 之前用BIT套Splay( http://www.cnblogs.com/JSZX11556/p/4625552.html )A过..但是还是线段树好写...而且快(常数比平衡树 ...

  7. 练习:一只豆瓣电影TOP250的爬虫

    练习:一只豆瓣电影TOP250爬虫 练习:一只豆瓣电影TOP250爬虫 ①创建project ②编辑items.py import scrapyclass DoubanmovieItem(scrapy ...

  8. SecureCRT, SecureFX连接Linux时中文乱码解决办法

    SecureCRT可以在GUI界面设置,但SecureFX没有设置界面.不过可以直接在配置文件中修改. 1. 找到配置文件夹(选项--全局选项,常规下的配置文件夹),默认是:C:\Documents  ...

  9. SeaJS 简单试用

    http://seajs.org/docs/#quick-start 感觉seajs的语法有点罗嗦... 它既有RequireJS的特点也有NodeJS引入模块的特点 例子是抄的官方的例子  在官方的 ...

  10. java调用C++ DLL库方法

    最近一个项目要开发网页端人脸识别项目,人脸识别的算法已经写好,是C++版,但是网页端要求使用Java后台,这就涉及到Java调用DLL的问题.经过查找,实现了一个简单的例子. 1.第一步,先在Java ...