LINUX最大线程数及最大进程数

本文探讨了Linux系统中线程的最大限制及其与系统资源的关系。详细分析了如何通过ulimit命令调整线程栈大小来增加可创建线程的数量,并介绍了与线程管理相关的内核特性。

转自http://www.cppblog.com/fwxjj/archive/2011/10/12/158108.html

查看最大线程数:

cat /proc/sys/kernel/threads-max

ulimit

User limits - limit the use of system-wide resources.

Syntax
ulimit [-acdfHlmnpsStuv] [limit]

Options

-S Change and report the soft limit associated with a resource. 
-H Change and report the hard limit associated with a resource. 

-a All current limits are reported. 
-c The maximum size of core files created. 
-d The maximum size of a process's data segment. 
-f The maximum size of files created by the shell(default option) 
-l The maximum size that may be locked into memory. 
-m The maximum resident set size. 
-n The maximum number of open file descriptors. 
-p The pipe buffer size. 
-s The maximum stack size. 
-t The maximum amount of cpu time in seconds. 
-u The maximum number of processes available to a single user. 
-v The maximum amount of virtual memory available to the process. 

ulimit provides control over the resources available to the shell and to processes started by it, on systems that allow such control.

If limit is given, it is the new value of the specified resource. Otherwise, the current value of the soft limit for the specified resource is printed, unless the `-H' option is supplied.

When setting new limits, if neither `-H' nor `-S' is supplied, both the hard and soft limits are set.

Values are in 1024-byte increments, except for `-t', which is in seconds, `-p', which is in units of 512-byte blocks, and `-n' and `-u', which are unscaled values.

The return status is zero unless an invalid option is supplied, a non-numeric argument other than unlimited is supplied as a limit, or an error occurs while setting a new limit.

ulimit is a bash built in command.

Ulimit命令
设置限制 可以把命令加到profile文件里,也可以在/etc/security/limits.conf文件中定义
限制。
命令参数
-a 显示所有限制
-c core文件大小的上限
-d 进程数据段大小的上限
-f shell所能创建的文件大小的上限
-m 驻留内存大小的上限
-s 堆栈大小的上限
-t 每秒可占用的CPU时间上限
-p 管道大小
-n 打开文件数的上限
-u 进程数的上限
-v 虚拟内存的上限
除可用Ulimit命令设置外,也可以在/etc/security/limits.conf文件中定义限制。
domino type item value
domino是以符号@开头的用户名或组名,*表示所有用户,type设置为hard or soft。item指
定想限制的资源。如cpu,core nproc or maxlogins。value是相应的限制值。

系统限制默认值

[root@flyinweb ~]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 32764
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 32764
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[root@flyinweb ~]# lsb_release -a
LSB Version: :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: CentOS
Description: CentOS release 5.2 (Final)
Release: 5.2
Codename: Final

linux 系统中单个进程的最大线程数有其最大的限制 PTHREAD_THREADS_MAX

这个限制可以在 /usr/include/bits/local_lim.h 中查看

对 linuxthreads 这个值一般是 1024,对于 nptl 则没有硬性的限制,仅仅受限于系统的资源

这个系统的资源主要就是线程的 stack 所占用的内存,用 ulimit -s 可以查看默认的线程栈大小,一般情况下,这个值是 8M

可以写一段简单的代码验证最多可以创建多少个线程

int main()  int  i = 0;  pthread_t  thread while  (1) {  if  (pthread_create(& thread , NULL, foo, NULL) != 0)  return i ++;  printf( "i = %d\n" , i);  }


试验显示,在 linuxthreads 上最多可以创建 381 个线程,之后就会返回 EAGAIN

在 nptl 上最多可以创建 382 个线程,之后就会返回 ENOMEM

这个值和理论完全相符,因为 32 位 linux 下的进程用户空间是 3G 的大小,也就是 3072M,用 3072M 除以 8M 得 384,但是实际上代码段和数据段等还要占用一些空间,这个值应该向下取整到 383,再减去主线程,得到 382。

那为什么 linuxthreads 上还要少一个线程呢?这可太对了,因为 linuxthreads 还需要一个管理线程

为了突破内存的限制,可以有两种方法

1) 用 ulimit -s 1024 减小默认的栈大小
2) 调用 pthread_create 的时候用 pthread_attr_getstacksize 设置一个较小的栈大小

要注意的是,即使这样的也无法突破 1024 个线程的硬限制,除非重新编译 C 库

相关内容:

一、2.4内核与2.6内核的主要区别
在2.4内核的典型系统上(AS3/RH9),线程是用轻量进程实现的,每个线程要占用一个进程ID,在服务器程序上,如果遇到高点击率访问,会造成进程表溢出,系统为了维护溢出的进程表,会有间歇的暂停服务现象,而2.6内核就不会发生由于大量线程的创建和销毁导致进程表溢出的问题
二、线程结束必须释放线程堆栈
就是说,线程函数必须调用pthread_exit()结束,否则直到主进程函数退出才释放,特别是2.6内核环境,线程创建速度飞快,一不小心立刻内存被吃光,这一点反倒是2.4内核环境好,因为2.4内核创建的是进程,而且线程创建速度比2.6内核慢几个数量级。特别提醒,在64位CPU,2.6内核创建线程的速度更加疯狂,要是太快的话,加上usleep ()暂停一点点时间比较好
三、不要编需要锁的线程应用
只有那些不需要互斥量的程序才能最大限度的利用线程编程带来的好处,否则只会更慢,2.6内核是抢占式内核,线程间共享冲突发生的几率远比2.4内核环境高,尤其要注意线程安全,否则就算是单CPU也会发生莫名其妙的内存不同步(CPU的高速缓存和主存内容不一致),Intel的新CPU为了性能使用NUMA架构,在线程编程中一定要注意扬长避短。
四、单进程服务器最大并发线程数与内存
很有趣,在默认的ulimit参数下,不修改内核头文件
AS3 512M内存最多1000并发持续连接
CentOS4.3 512M内存最多300并发持续连接
似乎是CentOS不如AS3,这里主要原因是ulimit的配置造成,两个系统默认的配置差距很大,要想单进程维持更多线程接收并发连接,就要尽量缩小 ulimit -s的参数,插更多的内存条,单进程服务器上2000并发一点都不难,POSIX默认的限制是每进程64线程,但NTPL并非纯正POSIX,不必理会这个限制,2.6内核下真正的限制是内存条的插槽数目(也许还有买内存的钱数)
最近几天的编程中,注意到在32位x86平台上2.6内核单进程创建最大线程数=VIRT上限/stack,与总内存数关系不大,32位x86系统默认的VIRT上限是3G(内存分配的3G+1G方式),默认 stack大小是10240K,因此单进程创建线程默认上限也就300(3072M / 10240K),用ulimit -s 修改stack到1024K则使上限升到大约3050。我手头没有64位系统,不知道2.6内核在64位上单进程创建线程上限(实际上是本人懒得在同事的机器上装fc4_x86_64)。
前些天买了一套廉价的64位x86系统(64位赛杨+杂牌915主板),安装了CentOS4.3的x86_64版本,跑了一遍下面的小程序,得到的结果是:在ulimit -s 4096的情况下,单进程最大线程数在16000多一点,用top看
VIRT 的上限是64G,也就是36位, cat /proc/cpuinfo的结果是:address sizes : 36 bits physical, 48 bits virtual, 和我想象的标准64位系统不同, 我一直以为64位系统的内存空间也是64位的
附注1:
单位里某BSD FANS用AMD64笔记本跑小程序测试线程创建速度(线程创建后立即phread_detach()然后紧跟着pthread_exit(),共计 100万个线程),同样源码OpenBSD竟然比FreeBSD快了3倍,什么时候OpenBSD也变得疯狂起来了?
附注2:
测试单进程创建线程上限C源码(test.c):

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> void * thread_null(void); int main(int argc, char*argv[]) unsigned int i; int rc; pthread_t pool_id[65536]; //线程ID sleep(1); //创建线程 for(i = 0; i < 65536; i++) { rc = pthread_create(pool_id + i, 0, (void*)thread_null, NULL); if (0 != rc) { fprintf(stderr, "pthread_create() failure\r\nMax pthread num is %d\r\n", i); exit(-1); fprintf(stdout, "Max pthread num is 65536\r\nYour system is power_full\r\n"); exit(0); void * thread_null(voidpthread_detach(pthread_self()); sleep(60); pthread_exit(NULL); }

编译:

[root@localhost test]# gcc test.c -o test -lpthread
[root@localhost test]# ulimit -s 10240
[root@localhost test]# ./test 
pthread_create() failure
Max pthread num is 305
[root@localhost test]# ulimit -s 1024 
[root@localhost test]# ./test 
pthread_create() failure
Max pthread num is 3054

以上结果在 CentOS release 5.2 (32Bit)系统上测试得到

<think>嗯,用户问的是Linux系统中最大线程数的配置和限制,特别是关于ulimit的使用。我需要先回忆一下相关知识,并结合提供的引用内容来整理答案。 首先,用户可能想知道如何查看当前的最大线程数限制。我记得ulimit命令可以检查这些限制,比如ulimit -u显示用户级别的进程数限制,而线程在Linux中通常被视为轻量级进程。所以应该提到使用ulimit -u来查看当前用户的最大进程数,也就是线程数限制。引用[3]中提到使用ulimit -u 1024,所以这个例子可以说明问题。 接下来,用户可能需要知道如何临时修改这个限制。这时候应该解释ulimit -u的新值,但要注意临时修改只在当前会话有效。引用[1]里提到了设置ulimit -n来调整文件目,这里可能需要类比到ulimit -u的设置。 然后是永久修改的方法,这涉及到系统配置文件。根据引用[3]和引用[4],/etc/security/limits.d/目录下的配置文件,比如90-nproc.conf,需要修改nproc的值。这里要说明如何编辑这些文件,将用户限制改为更大的值或者无限制,并注意root用户的默认设置。例如,引用[3]中的例子是将普通用户的限制从1024改大,或者注释掉原有行。 还需要提到其他可能影响线程数的系统级参,比如kernel.pid_max和threads-max。这部分可能需要补充一些知识,比如sysctl中的kernel.threads-max参,这不在提供的引用中,但属于常见配置。不过用户提供的引用中没有提到这个,所以是否要包括呢?可能应该简要提及,因为系统全局限制也会影响线程数,但主要依据引用内容的话,可能重点在用户级限制。 另外,用户可能会遇到的问题,比如无法登录或者su失败,如引用[2]和引用[3]所述,当达到最大线程数时会出现资源不可用的情况,这时候需要提醒用户注意不要设置过高,或者及时清理资源。 最后,生成相关问题时要围绕配置、查看、修改限制以及相关错误处理。例如,如何检查当前线程数,如何解决资源不足的错误,系统全局限制等。</think>### Linux系统最大线程数配置与限制详解 #### 一、查看当前线程数限制 1. **用户级限制** 使用`ulimit -u`命令可查看当前用户的最大进程数(含线程数)限制,例如: ```bash $ ulimit -u 1024 # 表示当前用户最多允许1024个线程[^3] ``` 2. **系统级限制** 通过`/proc/sys/kernel/threads-max`文件查看系统全局最大线程数: ```bash $ cat /proc/sys/kernel/threads-max 63704 # 系统最多允许63704个线程 ``` #### 二、修改线程数限制 1. **临时修改(会话级)** 通过`ulimit -u <值>`临时调整当前会话的限制: ```bash $ ulimit -u 4096 # 设置当前会话线程数上限为4096[^1] ``` 2. **永久修改(用户级)** 编辑配置文件`/etc/security/limits.d/90-nproc.conf`(CentOS/RHEL): ```bash # 将普通用户限制从1024改为2048 * soft nproc 2048 # 所有用户软限制 root soft nproc unlimited # root用户无限制[^3] ``` 修改后**重启系统**或重新登录生效。 3. **系统级全局限制** 修改`/etc/sysctl.conf`调整内核参: ```bash kernel.threads-max = 120000 # 设置系统最大线程数为12万 ``` 执行`sysctl -p`立即生效。 #### 三、关键配置文件说明 | 配置项 | 作用 | 典型值示例 | |--------------|-----------------------------|-----------------| | soft nproc | 用户警告阈值(可临时超出) | 2048 | | hard nproc | 用户绝对上限(不可超越) | 4096 | | threads-max | 系统总线程数限制 | 120000 | #### 四、常见问题排查 1. **资源不可用错误** 当出现`su: 无法设置用户ID: 资源暂时不可用`时,表明已达到线程数限制[^2],需清理线程或调整限制。 2. **多维度限制影响** 线程数同时受`nproc`(用户级)和`threads-max`(系统级)限制,需两者均满足[^4]。 ```bash # 统计当前线程总 $ ps -eLf | wc -l ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值