1.进程中创建线程的限制

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

#define MAX_THREADS 50000
#include <Windows.h>
#include <stdio.h>
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    while(1)
    {
        Sleep(100000);
    }
    return 0;
}
int main() {

DWORD dwThreadId[MAX_THREADS];
    HANDLE hThread[MAX_THREADS];
    void * stack[MAX_THREADS];
    for(int i = 0; i < MAX_THREADS; ++i)
    {

hThread[i] = CreateThread(0,0, ThreadProc, 0, CREATE_SUSPENDED, &dwThreadId[i]);
        if(0 == hThread[i])
        {
            DWORD e = GetLastError();
            if (e == 8)
            {
                printf("Out of Memory!\n",e);
            }
            else
            {
                printf("%d\r\n",e);
            }
            break;

}
        else
        {
            printf("%d:%d\r\n",i,hThread[i]);
        }

}
    ThreadProc(0);
}

程序的运行结果是:

【  】

2.如何突破2000个限制?

你也可以通过连接时修改默认栈大小,将其改的比较小,这样就可以多开一些线程。 如将默认栈的大小改成512K,这样理论上最多就可以开4096个线程。
    即使物理内存再大,一个进程中可以起的线程总要受到2GB这个内存空间的限制。比方说你的机器装了64GB物理内存,但每个进程的内存空间还是4GB,其中用户态可用的还是2GB。

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

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

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,048 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.”

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

#define MAX_THREADS 50000
#include <Windows.h>
#include <stdio.h>

DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    while(1)
    {
        Sleep(100000);
    }
    return 0;
}

int main() {

DWORD dwThreadId[MAX_THREADS];
    HANDLE hThread[MAX_THREADS];
    void * stack[MAX_THREADS];
    for(int i = 0; i < MAX_THREADS; ++i)
    {
        hThread[i] = CreateThread(0,512 * 1024, ThreadProc, 0, STACK_SIZE_PARAM_IS_A_RESERVATION | CREATE_SUSPENDED, &dwThreadId[i]);

if(0 == hThread[i])
        {
            DWORD e = GetLastError();
            if (e == 8)
            {
                printf("Out of Memory!\n",e);
            }
            else
            {
                printf("%d\r\n",e);
            }
            break;

}
        else
        {
            printf("%d:%d\r\n",i,hThread[i]);
        }

}
    ThreadProc(0);
}        

注意上面红色带下划线变化的部分!(0==>512 * 1024,加上了STACK_SIZE_PARAM_IS_A_RESERVATION字段)
程序的运行结果是:

【         】
可以开启的线程数增长了一倍!!

服务器端程序设计

如果你的服务器端程序设计成:来一个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
上面几句哈的核心的思想是:使用异步I/O,和一个线程处理多个客户请求!!

一个进程(Process)最多可以生成多少个线程(Thread)的更多相关文章

  1. windows 一个进程可以允许最大的线程数

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

  2. 如何在Linux中统计一个进程的线程数(转)

    方法一: /proc proc 伪文件系统,它驻留在 /proc 目录,这是最简单的方法来查看任何活动进程的线程数. /proc 目录以可读文本文件形式输出,提供现有进程和系统硬件相关的信息如 CPU ...

  3. (转)如何在Linux中统计一个进程的线程数

    如何在Linux中统计一个进程的线程数 原文:http://os.51cto.com/art/201509/491728.htm 我正在运行一个程序,它在运行时会派生出多个线程.我想知道程序在运行时会 ...

  4. 如何在 Linux 中统计一个进程的线程数

    编译自:http://ask.xmodulo.com/number-of-threads-process-linux.html作者: Dan Nanni原创:LCTT https://linux.cn ...

  5. 计算机必知必会:进程process与线程thread 进程定义为一个正在运行的程序的实例

    http://www.nowamagic.net/librarys/veda/detail/1741进程和线程这对概念的理解也是很难的,至今网络上可查的资料对其的理解出入都挺大,在不同的操作系统中,如 ...

  6. 多并发编程基础 之进程 Process

    原贴  https://www.cnblogs.com/gbq-dog/p/10299663.html 1. 进程的理论知识 1.1 操作系统的背景知识 顾名思义,进程即正在执行的一个过程.进程是对正 ...

  7. Python 进程(process)

    1. 进程 1.1 进程的创建 fork 正在运行着的代码,就称为进程 # 示例: import os # 注意: fork 函数,只在 Unix/Linux/Mac 上运行, windows 不可以 ...

  8. nodeJS之进程process对象

    前面的话 process对象是一个全局对象,在任何地方都能访问到它,通过这个对象提供的属性和方法,使我们可以对当前运行的程序的进程进行访问和控制.本文将详细介绍process对象 概述 process ...

  9. exit会结束一个进程

    #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include<stdlib.h ...

随机推荐

  1. 使用Bootstrap后,关于IE与Chrome显示字体的问题

    在做日志系统时,使用了Bootstrap,然后通过浏览器查看的页面效果如下 对比可以看到,同样的字体,IE显示的圆润些,而Chrome字体则丑很多.因为Chrome默认用宋体 在http://v3.b ...

  2. Log Shipping搭建

    1.    概述 SQL Server 使用日志传送,您可以自动将“主服务器”实例上“主数据库”内的事务日志备份发送到单独“辅助服务器”实例上的一个或多个“辅助数据库”.事务日志备份分别应用于每个辅助 ...

  3. verilog语法实例学习(6)

    函数和任务 函数 https://wenku.baidu.com/view/d31d1ba8dd3383c4bb4cd283.html verilog中函数的目的是允许代码写成模块的方式而不是定义独立 ...

  4. RV32I指令集

    RV32I是最基本的32位Base指令集,它支持32位寻址空间,支持字节地址访问,仅支持小端格式(little-endian,高地址高位,低地址地位),寄存器也是32位整数寄存器.RV32I指令集的目 ...

  5. 如何回收vRealize Automation里被分配出去了的IP地址

    在vRealize里写代码部署虚机,时间长了,便出现了很多虚机在vCenter里不存在,但在vRealize里还存在的这台虚机的注册信息的现象.最直接的后果是,这些影子虚机会占着IP池里的IP地址不放 ...

  6. Java程序员须知的七个日志管理工具

    本文由 ImportNew - 赖 信涛 翻译自 takipiblog.欢迎加入翻译小组.转载请见文末要求. Splunk vs. Sumo Logic vs. LogStash vs. GrayLo ...

  7. android 桌面小工具(Widget)开发教程

    刚学做了哥Widget,感觉不错哦,先来秀下效果(用朋友手机截的图) 这个Widget会每隔5秒钟自动切换内容和图片,图片最好使用小图,大图会导致你手机桌面(UI)线程卡顿 教程开始: 1.首先创建一 ...

  8. 在UTF-8中,一个汉字为什么需要三个字节?(转)

    http://www.cnblogs.com/web21/p/6092414.html UNICODE是万能编码,包含了所有符号的编码,它规定了所有符号在计算机底层的二进制的表示顺序.有关Unicod ...

  9. window下配置Apache2服务器

    1:去Apache.org下载安装包 http://httpd.apache.org/ 2:解压到某一个目录 3:修改httpd.conf(Apache的解压目录和端口号) 4:管理员方式启动cmd执 ...

  10. Cognos11只需简单几步创建你的Dashboard

    一.环境 操作系统:win10 数据库   :SQLserver 2008 R2 软件版本:IBM Cognos Analytics 11.0.6 浏览器   :IE 11 二.开始创建仪表板 2.1 ...