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. remote: GitLab: You are not allowed to push code to protected branches on this project.

    "C:\Program Files\Git\bin\git.exe" push --recurse-submodules=check --progress "origin ...

  2. iOS:仿写探探App动画

    一.简单介绍 探探动画比较新颖,这也是它在众多交友软件中火热的一个特色.实现这种动画的方式可以有两种方式实现: 1.使用转场动画实现  2.使用CollectionView自定义布局实现, 此处我提供 ...

  3. 从零开始学C++之模板(三):缺省模板参数(借助标准模板容器实现Stack模板)、成员模板、关键字typename

    一.缺省模板参数 回顾前面的文章,都是自己管理stack的内存,无论是链栈还是数组栈,能否借助标准模板容器管理呢?答案是肯定的,只需要多传一个模板参数即可,而且模板参数还可以是缺省的,如下: temp ...

  4. K3 LEDE固件更改FRP客户端版本

    1.下载文件 /usr/bin/wget --no-check-certificate https://github.com/fatedier/frp/releases/download/v0.23. ...

  5. Wildcard Matching leetcode java

    题目: Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single charact ...

  6. TensorFlow实战12:Bidirectional LSTM Classifier

    https://blog.csdn.net/felaim/article/details/70300362 1.双向递归神经网络简介 双向递归神经网络(Bidirectional Recurrent ...

  7. GIT 使用cherry-pick 重演其他分支的提交

    在使用Git时是否会遇到这样的问题: 你正在使用Git进行版本控制,某天你接着昨天的工作了提交了N个提交,结果在合并远程分支的时候才发现原来你在工作之前没有注意到你要提交的分支状态 结果导致你本来要提 ...

  8. gl.h included before glew.h

      So I'm trying to move my OpenGL code from Main() into a specific class that will handle the 3D gra ...

  9. 清空npm缓存

    nodejs 清空 npm 缓存 npm cache clean -f

  10. OpenGL ES 3.0顶点着色器(一)

    OpenGL ES 3.0流程图 1.Vertex Shader(顶点着色器) 顶点着色实现了一种通用的可编程方法操作顶点. 顶点着色器的输入包括以下几个: • Shader program.程序的顶 ...