首页
社区
课程
招聘
[旧帖] 请教一下是什么限制了WINDOWS的进程数量 0.00雪花
发表于: 2011-11-7 22:56 6479

[旧帖] 请教一下是什么限制了WINDOWS的进程数量 0.00雪花

2011-11-7 22:56
6479
最近研究挂号 但是发现一个再好的配置 也开不了多少进程 一般200-500多个 系统就会开始出现问题 比如新的程序不能打开 在桌面上点右键弹出来的菜单不完整 点击菜单没有任何反应 把进程关闭后就好了 感觉像是资源不够了 但是 查看任务管理器 CPU和内存还剩余很多  然后我就怀疑硬盘 之类的  就到PE里面 (PE全部运行在内存中 ) 反复打开记事本 也是一样的效果 内存和CPU使用了极少的资源 但是无法打开更多的进程
百度了相关的资料 大家都说进程数量理论上没有限制 但是在我的实际测试当中  XP 2003 都只能开200-500个进程  WIN7稍微多一点点

论坛高手众多 特来请教一下 是什么限制了windows的进程数量?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 170
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
网上找到一篇资料 不知道和这个有没有关系

默认情况下,一个线程的栈要预留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-triggered readiness 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

  --------------------

  附:Win32将低区的2GB留给进程使用, 高区的2GB则留给系统使用。

  Linux将高位1GB留给内核,低位3GB留给进程。
2011-11-7 23:09
0
雪    币: 347
活跃值: (40)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
单进程下的线程数受2G用户空间限制,所以通过调整线程的堆栈大小可以增加。

但是进程的最大上限,这个好像牵扯的东西比较多。非分页池的大小有限,句柄总数应该也有限。如果进程是GUI类型的话,还占用GDI资源。

我测试了一下简单的console程序,就主线程循环延时printf,win2003 32bit企业版的虚拟机,总进程数到了888,测试程序的进程数到了852,也能再开,但是反应已经很慢了.
2011-11-8 07:01
0
雪    币: 5
活跃值: (514)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
确实是这样子的,以前做某项目的性能测试工具,创建一定的线程,就不能再创建了。
2011-11-8 08:36
0
雪    币: 85
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
好帖子,开了个先河,我以前只会用工具为XP系统将10或512的线程开到2048(扫IP用),却一直不明白其中机理,看了上面的内容现在有点点懂了。。。
2011-11-8 12:19
0
游客
登录 | 注册 方可回帖
返回