ulimit命令查看和更改系統限制
ulimit命令詳解
ulimit用於shell啟動進程所占用的資源,可以用來設置系統的限制
語法格式
ulimit [-acdfHlmnpsStvw] [size]
在/etc/security/limits.conf文件中定義
限制。
命令參數 描述 例子
-H 設置硬資源限制,一旦設置不能增加。 ulimit – Hs 64;限制硬資源,線程棧大小為 64K。
-S 設置軟資源限制,設置后可以增加,但是不能超過硬資源設置。 ulimit – Sn 32;限制軟資源,32 個文件描述符。
-a 顯示當前所有的 limit 信息 ulimit – a;顯示當前所有的 limit 信息
-c 最大的 core 文件的大小, 以 blocks 為單位 ulimit – c unlimited; 對生成的 core 文件的大小不進行限制
-d 進程最大的數據段的大小,以 Kbytes 為單位 ulimit -d unlimited;對進程的數據段大小不進行限制
-f 進程可以創建文件的最大值,以 blocks 為單位 ulimit – f 2048;限制進程可以創建的最大文件大小為 2048 blocks
-l 最大可加鎖內存大小,以 Kbytes 為單位 ulimit – l 32;限制最大可加鎖內存大小為 32 Kbytes
-m 最大內存大小,以 Kbytes 為單位 ulimit – m unlimited;對最大內存不進行限制
-n 可以打開最大文件描述符的數量 ulimit – n 128;限制最大可以使用 128 個文件描述符
-p 管道緩沖區的大小,以 Kbytes 為單位 ulimit – p 512;限制管道緩沖區的大小為 512 Kbytes
-s 線程棧大小,以 Kbytes 為單位 ulimit – s 512;限制線程棧的大小為 512 Kbytes
-t 最大的 CPU 占用時間,以秒為單位 ulimit – t unlimited;對最大的 CPU 占用時間不進行限制
-u 用戶最大可用的進程數 ulimit – u 64;限制用戶最多可以使用 64 個進程
-v 進程最大可用的虛擬內存,以 Kbytes 為單位 ulimit – v 200000;限制最大可用的虛擬內存為 200000 Kbytes
我們可以使用ulimit -a查看我們系統的所有限制
當然我們都知道linux大部分的命令設置都是臨時生效,而且ulimit命令只對當前終端生效
如果需要永久生效的話,我們有兩種方法,
一種是將命令寫至profile和bashrc中,相當於在登陸時自動動態修改限制
還有一種就是在/etc/security/limits.conf中添加記錄(需重啟生效,並且在/etc/pam.d/中的seesion有使用到limit模塊)。
limits.conf文件附錄
在/etc/security/limits.conf修改限制的格式如下
domino type item value
參數 描述
domino 是以符號@開頭的用戶名或組名,*表示所有用戶
type 設置為hard or soft
item 指定想限制的資源。如cpu,core nproc or maxlogins
value 是相應的
最大進程數目
LINUX中進程的最大理論數計算
每個進程都要在全局段描述表GDT中占據兩個表項
每個進程的局部段描述表LDT都作為一個獨立的段而存在,在全局段描述表GDT中要有一個表項指向這個段的起始地址,並說明該段的長度以及其他一些 參數。除上之外,每個進程還有一個TSS結構(任務狀態段)也是一樣。所以,每個進程都要在全局段描述表GDT中占據兩個表項。
GDT的容量有多大呢?
段寄存器中用作GDT表下標的位段寬度是13位,所以GDT中可以有213=8192213=8192個描述項。
除一些系統的開銷(例如GDT中的第2項和第3項分別用於內核 的代碼段和數據段,第4項和第5項永遠用於當前進程的代碼段和數據段,第1項永遠是0,等等)以外,尚有8180個表項可供使用,所以理論上系統中最大的 進程數量是8180/2=40908180/2=4090。
所以系統中理論上最大的進程數是4090
系統中可創建的進程數實際值
linux內核通過進程標識值(process identification value)-PID來標示進程,PID是一個數,類型位pid_t, 實際上就是int類型
為了與老版本的Unix或者Linux兼容,PID的最大值默認設置位32768(short int 短整型的最大值)。
查看
可以使用cat /proc/sys/kernel/pid_max來查看系統中可創建的進程數實際值
修改
ulimit -u 65535
1
設置完以后,雖然我們設置戶創建進程數的硬限制和軟限制都是65535,但是我們還不能使用創建65535個進程
我們在Linux還需要設置內核參數kernel.pid_max,這個參數我默認安裝都是32768,
所以即使使用root帳戶,卻不設置這個內核參數,整個系統最多可以創建的進程數就是32768,所以我們需要進行如下設置:
sysctl -w kernel.pid_max=65535
1
最大線程數
linux 系統中單個進程的最大線程數有其最大的限制 PTHREAD_THREADS_MAX
這個限制可以在/usr/include/bits/local_lim.h中查看
對 linuxthreads 這個值一般是 1024,對於 nptl 則沒有硬性的限制,僅僅受限於系統的資源
這個系統的資源主要就是線程的 stack 所占用的內存,用 ulimit -s 可以查看默認的線程棧大小,一般情況下,這個值是8M=8192KB
可以寫一段簡單的代碼驗證最多可以創建多少個線程
include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void func()
{
}
int main(void)
{
int i = 0;
pthread_t thread;
while ( 1 )
{
if (pthread_create(&thread, NULL, func, NULL) != 0)
{
return;
}
i++;
printf("i = %d\n", i);
}
return EXIT_SUCCESS;
}
試驗顯示,在我們的系統(Ubuntu-14.04-LTS-64bit)中linuxthreads 上最多可以創建 381 個線程,之后就會返回 EAGAIN
LINUX中單個進程理論上可以創建的最大線程數
而32位系統中,可以穿件381個線程,這個值和理論完全相符,因為 32 位 linux 下的進程用戶空間是 3G 的大小,也就是 3072M,用3072M/8M=3843072M/8M=384,但是實際上代碼段和數據段等還要占用一些空間,這個值應該向下取整到 383,再減去主線程,得到 382。
那為什么 linuxthreads 上還要少一個線程呢?這可太對了,因為 linuxthreads 還需要一個管理線程
為了突破內存的限制,可以有兩種方法
用ulimit -s 1024減小默認的棧大小
調用pthread_create的時候用pthread_attr_getstacksize設置一個較小的棧大小
要注意的是,即使這樣的也無法突破1024 個線程的硬限制,除非重新編譯 C 庫
最大打開文件數
file-max系統最大打開文件描述符數
/proc/sys/fs/file-max中指定了系統范圍內所有進程可打開的文件句柄的數量限制(系統級別, kernel-level).
The value in file-max denotes the maximum number of file handles that the Linux kernel will allocate).
當收到”Too many open files in system”這樣的錯誤消息時, 就應該曾加這個值了.
對於2.2的內核, 還需要考慮inode-max, 一般inode-max設置為file-max的4倍. 對於2.4及以后的內核, 沒有inode-max這個文件了.
查看實際值
可以使用cat /proc/sys/fs/file-max來查看當前系統中單進程可打開的文件描述符數目
186405
設置
臨時性
echo 1000000 > /proc/sys/fs/file-max
永久性:在/etc/sysctl.conf中設置
fs.file-max = 1000000
nr_open是單個進程可分配的最大文件數
內核支持的最大file handle數量,即一個進程最多使用的file handle數
the maximum number of files that can be opened by process。
A process cannot use more than NR_OPEN file descriptors.
一個進程不能使用超過NR_OPEN文件描述符。
1
2
nofile進程最大打開文件描述符數
查看實際值
ulimit -n
當然默認查看的是軟資源限制值soft limit,如果想要查看系統硬件所能支持的單進程最大打開文件描述符號的數目,可以使用ulimit -Hn
設置
臨時性
通過ulimit -Sn設置最大打開文件描述符數的soft limit,注意soft limit不能大於hard limit(ulimit -Hn可查看hard limit)
另外ulimit -n默認查看的是soft limit,但是ulimit -n 1800000則是同時設置soft limit和hard limit。
對於非root用戶只能設置比原來小的hard limit。
永久性
上面的方法只是臨時性的,注銷重新登錄就失效了,而且不能增大hard limit,只能在hard limit范圍內修改soft limit。
若要使修改永久有效,則需要在/etc/security/limits.conf中進行設置(需要root權限),可添加如下兩行,表示用戶chanon最大打開文件描述符數的soft limit為1800000,hard limit為2000000。以下設置需要注銷之后重新登錄才能生效:
chanon soft nofile 102400
chanon hard nofile 409600
1
2
設置nofile的hard limit還有一點要注意的就是hard limit不能大於/proc/sys/fs/nr_open,假如hard limit大於nr_open,注銷后無法正常登錄。
可以修改nr_open的值:
echo 2000000 > /proc/sys/fs/nr_open
file-max, nr_open, onfile之間的關系
針對用戶打開最大文件數的限制, 在limits.conf對應的nofile,不管是man手冊還是文件中說明都只是一句話
“maximum number of open files”,
它其實對應是單個進程能打開的最大文件數,通常為了省事,我們想取消它的限制
根據man手冊中,“values -1, unlimited or infinity indicating no limit”,-1、unlimited、infinity都是表明不做限制
可是當你實際給nofile設置成這個值,等你重啟就會發現無法登錄系統了。
由此可見,nofile是有一個上限的,同時用ulimit測試:
ulimit -n unlimited
1
bash: ulimit: open files: cannot modify limit: 不允許的操作
寫一個簡單的for循環得出:
for V in `seq 100000 10000000`;do ulimit -n $V;[[ $? != 0 ]]&&break;done
1
再執行ulimit -n ,可以看到1048576就是nofile的最大值了,但為什么是這個值?
1024∗1024=10485761024∗1024=1048576,當然這並沒有什么卵用。
再跟蹤一下我們就會發現這個值其實是由內核參數nr_open定義的:
cat /proc/sys/fs/nr_open
1
到此我們就要說起nr_open,與file-max了,網上在說到設置最大文件數時偶爾有些帖子也說到要修改file-max,字面上看file-max確實像是對應最大文件數,而在linux內核文檔中它們兩的解釋是:
file-max:
The value in file-max denotes the maximum number of file-
handles that the Linux kernel will allocate. When you get lots
of error messages about running out of file handles, you might
want to increase this limit
執行:grep -r MemTotal /proc/meminfo | awk ‘{printf(“%d”,$2/10)}’,可以看到與file-max是相近的;
nr_open:
This denotes the maximum number of file-handles a process can
allocate. Default value is 1024*1024 (1048576) which should be
enough for most machines. Actual limit depends on RLIMIT_NOFILE
resource limit.
file-handles(即文件句柄),然后相比而言在UNIX/LINUX中我們接觸更多是file discriptor(FD,即文件描述符),似乎file-handle在windows中是一個類似file discrptor的東東,但是我們討論的是linux,再google一下,我們可以精確到c語言中這兩個概念的區別,
據他們的討論file-handle應該是一個高層的對象,使用fopen,fread等函數來調用,而FD是底層的一個對象,可以通過open,read等函數來調用。
到此,我們應該可以下一個大致的結論了,file-max是內核可分配的最大文件數,nr_open是單個進程可分配的最大文件數,所以在我們使用ulimit或limits.conf來設置時,如果要超過默認的1048576值時需要先增大nr_open值(sysctl -w fs.nr_open=100000000或者直接寫入sysctl.conf文件)。當然百萬級別的單進程最大file-handle打開數應該也夠用了吧。。
所有進程打開的文件描述符數不能超過/proc/sys/fs/file-max
單個進程打開的文件描述符數不能超過user limit中nofile的soft limit
nofile的soft limit不能超過其hard limit
nofile的hard limit不能超過/proc/sys/fs/nr_open
————————————————
版權聲明:本文為CSDN博主「CHENG Jian」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/gatieme/article/details/51058797