深入探討linux下進程的最大線程數(shù)、進程最大數(shù)、進程打開的文件數(shù)
更新時間:2013年05月27日 12:04:30 作者:
本篇文章是對linux下進程的最大線程數(shù)、進程最大數(shù)、進程打開的文件數(shù)進行了詳細(xì)的分析介紹,需要的朋友參考下
=====最大線程數(shù)====
linux 系統(tǒng)中單個進程的最大線程數(shù)有其最大的限制 PTHREAD_THREADS_MAX
這個限制可以在 /usr/include/bits/local_lim.h 中查看
對 linuxthreads 這個值一般是 1024,對于 nptl 則沒有硬性的限制,僅僅受限于系統(tǒng)的資源
這個系統(tǒng)的資源主要就是線程的 stack 所占用的內(nèi)存,用 ulimit -s 可以查看默認(rèn)的線程棧大小,一般情況下,這個值是 8M
可以寫一段簡單的代碼驗證最多可以創(chuàng)建多少個線程
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 上最多可以創(chuàng)建 381 個線程,之后就會返回 EAGAIN
在 nptl 上最多可以創(chuàng)建 382 個線程,之后就會返回 ENOMEM
這個值和理論完全相符,因為 32 位 linux 下的進程用戶空間是 3G 的大小,也就是 3072M,用 3072M 除以 8M 得 384,但是實際上代碼段和數(shù)據(jù)段等還要占用一些空間,這個值應(yīng)該向下取整到 383,再減去主線程,得到 382。
那為什么 linuxthreads 上還要少一個線程呢?這可太對了,因為 linuxthreads 還需要一個管理線程
為了突破內(nèi)存的限制,可以有兩種方法
1) 用 ulimit -s 1024 減小默認(rèn)的棧大小
2) 調(diào)用 pthread_create 的時候用 pthread_attr_getstacksize 設(shè)置一個較小的棧大小
要注意的是,即使這樣的也無法突破 1024 個線程的硬限制,除非重新編譯 C 庫 <=此處值得討論,我在ubuntu 7.04+3G內(nèi)存上用ulimit -s 1024,則可以得到3054個線程。
===============進程最大數(shù)=================
LINUX中進程的最大理論數(shù)計算:
每個進程的局部段描述表LDT都作為一個獨立的段而存在,在全局段描述表GDT中要有一個表項指向這個段的起始地址,并說明該段的長度以及其他一些 參數(shù)。除上之外,每個進程還有一個TSS結(jié)構(gòu)(任務(wù)狀態(tài)段)也是一樣。所以,每個進程都要在全局段描述表GDT中占據(jù)兩個表項。那么,GDT的容量有多大 呢?段寄存器中用作GDT表下標(biāo)的位段寬度是13位,所以GDT中可以有8192個描述項。除一些系統(tǒng)的開銷(例如GDT中的第2項和第3項分別用于內(nèi)核 的代碼段和數(shù)據(jù)段,第4項和第5項永遠(yuǎn)用于當(dāng)前進程的代碼段和數(shù)據(jù)段,第1項永遠(yuǎn)是0,等等)以外,尚有8180個表項可供使用,所以理論上系統(tǒng)中最大的 進程數(shù)量是4090。
====重新編譯內(nèi)核來修改進程打開的最大文件數(shù)和修改listen偵聽隊列====
用“ulimit -a”能看到這些限制,如:
[root@HQtest root]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 2047
virtual memory (kbytes, -v) unlimited
用ulimit ?n 10240 修改打開的文件數(shù)目變?yōu)?10240
雖然使用ulimit ?a 能看到變?yōu)?0240,不過我在做壓力測試的時候,當(dāng)超過1024個用戶時,服務(wù)就會down機。
最后只有重新編譯了內(nèi)核,編譯內(nèi)核后一切OK!
操作方法如下:
不同的Linux內(nèi)核版本有不同的調(diào)整方法,
在Linux內(nèi)核2.2.x中能用如下命令修改:
# echo '8192' > /proc/sys/fs/file-max
# echo '32768' > /proc/sys/fs/inode-max
并將以上命令加到/etc/rc.c/rc.local文件中,以使系統(tǒng)每次重新啟動時設(shè)置以上值。
在Linux內(nèi)核2.4.x中需要修改原始碼,然后重新編譯內(nèi)核才生效。編輯Linux內(nèi)核原始碼中的 include/linux/fs.h文件,
將 NR_FILE 由8192改為 65536,將NR_RESERVED_FILES 由10 改為 128。編輯fs/inode.c 文件將 MAX_INODE 由16384改為262144。
一般情況下,最大打開文件數(shù)比較合理的設(shè)置為每4M物理內(nèi)存256,比如256M內(nèi)存能設(shè)為16384,
而最大的使用的i節(jié)點的數(shù)目應(yīng)該是最大打開文件數(shù)目的3倍到4倍。
linux 系統(tǒng)中單個進程的最大線程數(shù)有其最大的限制 PTHREAD_THREADS_MAX
這個限制可以在 /usr/include/bits/local_lim.h 中查看
對 linuxthreads 這個值一般是 1024,對于 nptl 則沒有硬性的限制,僅僅受限于系統(tǒng)的資源
這個系統(tǒng)的資源主要就是線程的 stack 所占用的內(nèi)存,用 ulimit -s 可以查看默認(rèn)的線程棧大小,一般情況下,這個值是 8M
可以寫一段簡單的代碼驗證最多可以創(chuàng)建多少個線程
復(fù)制代碼 代碼如下:
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 上最多可以創(chuàng)建 381 個線程,之后就會返回 EAGAIN
在 nptl 上最多可以創(chuàng)建 382 個線程,之后就會返回 ENOMEM
這個值和理論完全相符,因為 32 位 linux 下的進程用戶空間是 3G 的大小,也就是 3072M,用 3072M 除以 8M 得 384,但是實際上代碼段和數(shù)據(jù)段等還要占用一些空間,這個值應(yīng)該向下取整到 383,再減去主線程,得到 382。
那為什么 linuxthreads 上還要少一個線程呢?這可太對了,因為 linuxthreads 還需要一個管理線程
為了突破內(nèi)存的限制,可以有兩種方法
1) 用 ulimit -s 1024 減小默認(rèn)的棧大小
2) 調(diào)用 pthread_create 的時候用 pthread_attr_getstacksize 設(shè)置一個較小的棧大小
要注意的是,即使這樣的也無法突破 1024 個線程的硬限制,除非重新編譯 C 庫 <=此處值得討論,我在ubuntu 7.04+3G內(nèi)存上用ulimit -s 1024,則可以得到3054個線程。
===============進程最大數(shù)=================
LINUX中進程的最大理論數(shù)計算:
每個進程的局部段描述表LDT都作為一個獨立的段而存在,在全局段描述表GDT中要有一個表項指向這個段的起始地址,并說明該段的長度以及其他一些 參數(shù)。除上之外,每個進程還有一個TSS結(jié)構(gòu)(任務(wù)狀態(tài)段)也是一樣。所以,每個進程都要在全局段描述表GDT中占據(jù)兩個表項。那么,GDT的容量有多大 呢?段寄存器中用作GDT表下標(biāo)的位段寬度是13位,所以GDT中可以有8192個描述項。除一些系統(tǒng)的開銷(例如GDT中的第2項和第3項分別用于內(nèi)核 的代碼段和數(shù)據(jù)段,第4項和第5項永遠(yuǎn)用于當(dāng)前進程的代碼段和數(shù)據(jù)段,第1項永遠(yuǎn)是0,等等)以外,尚有8180個表項可供使用,所以理論上系統(tǒng)中最大的 進程數(shù)量是4090。
====重新編譯內(nèi)核來修改進程打開的最大文件數(shù)和修改listen偵聽隊列====
用“ulimit -a”能看到這些限制,如:
復(fù)制代碼 代碼如下:
[root@HQtest root]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 2047
virtual memory (kbytes, -v) unlimited
用ulimit ?n 10240 修改打開的文件數(shù)目變?yōu)?10240
雖然使用ulimit ?a 能看到變?yōu)?0240,不過我在做壓力測試的時候,當(dāng)超過1024個用戶時,服務(wù)就會down機。
最后只有重新編譯了內(nèi)核,編譯內(nèi)核后一切OK!
操作方法如下:
不同的Linux內(nèi)核版本有不同的調(diào)整方法,
在Linux內(nèi)核2.2.x中能用如下命令修改:
復(fù)制代碼 代碼如下:
# echo '8192' > /proc/sys/fs/file-max
# echo '32768' > /proc/sys/fs/inode-max
并將以上命令加到/etc/rc.c/rc.local文件中,以使系統(tǒng)每次重新啟動時設(shè)置以上值。
在Linux內(nèi)核2.4.x中需要修改原始碼,然后重新編譯內(nèi)核才生效。編輯Linux內(nèi)核原始碼中的 include/linux/fs.h文件,
將 NR_FILE 由8192改為 65536,將NR_RESERVED_FILES 由10 改為 128。編輯fs/inode.c 文件將 MAX_INODE 由16384改為262144。
一般情況下,最大打開文件數(shù)比較合理的設(shè)置為每4M物理內(nèi)存256,比如256M內(nèi)存能設(shè)為16384,
而最大的使用的i節(jié)點的數(shù)目應(yīng)該是最大打開文件數(shù)目的3倍到4倍。
相關(guān)文章
C++右值引用與移動構(gòu)造函數(shù)基礎(chǔ)與應(yīng)用詳解
左值和右值都是針對表達(dá)式,左值是指表達(dá)式結(jié)束后依然存在的持久對象,右值是指表達(dá)式結(jié)束時就不再存在的臨時對象,下面這篇文章主要給大家介紹了關(guān)于C++11右值引用和移動語義的相關(guān)資料,需要的朋友可以參考下2023-02-02GCC 編譯使用動態(tài)鏈接庫和靜態(tài)鏈接庫的方法
根據(jù)鏈接時期的不同,庫又有靜態(tài)庫和動態(tài)庫之分,有別于靜態(tài)庫,動態(tài)庫的鏈接是在程序執(zhí)行的時候被鏈接的2013-03-03C++實現(xiàn)LeetCode(19.移除鏈表倒數(shù)第N個節(jié)點)
這篇文章主要介紹了C++實現(xiàn)LeetCode(19.移除鏈表倒數(shù)第N個節(jié)點),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07C++?Boost?MultiArray簡化使用多維數(shù)組庫
Boost是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱2022-11-11