如何使用 ulimit
ulimit 通過一些引數選項來管理不同種類的系統資源。在本節,我們將講解這些引數的使用。
ulimit 命令的格式為:ulimit [options] [limit]
具體的 options 含義以及簡單示例可以參考以下表格。
表 1. ulimit 引數說明
選項 [options] | 含義 | 例子 |
---|---|---|
-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:
- 在使用者的啟動指令碼中
如果使用者使用的是 bash,就可以在使用者的目錄下的 .bashrc 檔案中,加入 ulimit – u 64,來限制使用者最多可以使用 64 個程式。此外,可以在與 .bashrc 功能相當的啟動指令碼中加入 ulimt。
- 在應用程式的啟動指令碼中
如果使用者要對某個應用程式 myapp 進行限制,可以寫一個簡單的指令碼 startmyapp。
ulimit – s 512 myapp
以後只要通過指令碼 startmyapp 來啟動應用程式,就可以限制應用程式 myapp 的執行緒棧大小為 512K。
- 直接在控制檯輸入
user@tc511-ui:~>ulimit – p 256
限制管道的緩衝區為 256K。
使用者程式的有效範圍
ulimit 作為對資源使用限制的一種工作,是有其作用範圍的。那麼,它限制的物件是單個使用者,單個程式,還是整個系統呢?事實上,ulimit 限制的是當前 shell 程式以及其派生的子程式。舉例來說,如果使用者同時執行了兩個 shell 終端程式,只在其中一個環境中執行了 ulimit – s 100,則該 shell 程式裡建立檔案的大小收到相應的限制,而同時另一個 shell 終端包括其上執行的子程式都不會受其影響:
Shell 程式 1
ulimit – s 100 cat testFile > newFile File size limit exceeded
Shell 程式 2
cat testFile > newFile ls – s newFile 323669 newFile
那麼,是否有針對某個具體使用者的資源加以限制的方法呢?答案是有的,方法是通過修改系統的 /etc/security/limits 配置檔案。該檔案不僅能限制指定使用者的資源使用,還能限制指定組的資源使用。該檔案的每一行都是對限定的一個描述,格式如下:
<domain> <type> <item> <value>
domain 表示使用者或者組的名字,還可以使用 * 作為萬用字元。Type 可以有兩個值,soft 和 hard。Item 則表示需要限定的資源,可以有很多候選值,如 stack,cpu,nofile 等等,分別表示最大的堆疊大小,佔用的 cpu 時間,以及開啟的檔案數。通過新增對應的一行描述,則可以產生相應的限制。例如:
* hard noflle 100
該行配置語句限定了任意使用者所能建立的最大檔案數是 100。
現在已經可以對程式和使用者分別做資源限制了,看似已經足夠了,其實不然。很多應用需要對整個系統的資源使用做一個總的限制,這時候我們需要修改 /proc 下的配置檔案。/proc 目錄下包含了很多系統當前狀態的引數,例如 /proc/sys/kernel/pid_max,/proc/sys/net/ipv4/ip_local_port_range 等等,從檔案的名字大致可以猜出所限制的資源種類。由於該目錄下涉及的檔案眾多,在此不一一介紹。有興趣的讀者可開啟其中的相關檔案查閱說明。
ulimit 管理系統資源的例子
ulimit 提供了在 shell 程式中限制系統資源的功能。本章列舉了一些使用 ulimit 對使用者程式進行限制的例子,詳述了這些限制行為以及對應的影響,以此來說明 ulimit 如何對系統資源進行限制,從而達到調節系統效能的功能。
使用 ulimit 限制 shell 的記憶體使用
在這一小節裡向讀者展示如何使用 – d,– m 和 – v 選項來對 shell 所使用的記憶體進行限制。
首先我們來看一下不設定 ulimit 限制時呼叫 ls 命令的情況:
圖 2. 未設定 ulimit 時 ls 命令使用情況
大家可以看到此時的 ls 命令執行正常。下面設定 ulimit:
>ulimit -d 1000 -m 1000 -v 1000
這裡再溫習一下前面章節裡介紹過的這三個選項的含義:
-d:設定資料段的最大值。單位:KB。
-m:設定可以使用的常駐記憶體的最大值。單位:KB。
-v:設定虛擬記憶體的最大值。單位:KB。
通過上面的 ulimit 設定我們已經把當前 shell 所能使用的最大記憶體限制在 1000KB 以下。接下來我們看看這時執行 ls 命令會得到什麼樣的結果:
haohe@sles10-hehao:~/code/ulimit> ls test -l /bin/ls: error while loading shared libraries: libc.so.6: failed to map segment from shared object: Cannot allocate memory
從上面的結果可以看到,此時 ls 執行失敗。根據系統給出的錯誤資訊我們可以看出是由於呼叫 libc 庫時記憶體分配失敗而導致的 ls 出錯。那麼我們來看一下這個 libc 庫檔案到底有多大:
圖 3. 檢視 libc 檔案大小
從上面的資訊可以看出,這個 libc 庫檔案的大小是 1.5MB。而我們用 ulimit 所設定的記憶體使用上限是 1000KB,小於 1.5MB,這也就充分證明了 ulimit 所起到的限制 shell 記憶體使用的功能。
使用 ulimit 限制 shell 建立的檔案的大小
接下來向讀者展示如何使用 -f 選項來對 shell 所能建立的檔案大小進行限制。
首先我們來看一下,沒有設定 ulimit -f 時的情況:
圖 4. 檢視檔案
現有一個檔案 testFile 大小為 323669 bytes,現在使用 cat 命令來建立一個 testFile 的 copy:
圖 5. 未設定 ulimit 時建立複本
從上面的輸出可以看出,我們成功的建立了 testFile 的拷貝 newFile。
下面我們設定 ulimt – f 100:
> ulimit -f 100
-f 選項的含義是:用來設定 shell 可以建立的檔案的最大值。單位是 blocks。
現在我們再來執行一次相同的拷貝命令看看會是什麼結果:
圖 6. 設定 ulimit 時建立複本
這次建立 testFile 的拷貝失敗了,系統給出的出錯資訊時檔案大小超出了限制。在 Linux 系統下一個 block 的預設大小是 512 bytes。所以上面的 ulimit 的含義就是限制 shell 所能建立的檔案最大值為 512 x 100 = 51200 bytes,小於 323669 bytes,所以建立檔案失敗,符合我們的期望。這個例子說明了如何使用 ulimit 來控制 shell 所能建立的最大檔案。
使用 ulimit 限制程式所能建立的 socket 數量
考慮一個現實中的實際需求。對於一個 C/S 模型中的 server 程式來說,它會為多個 client 程式請求建立多個 socket 埠給與響應。如果恰好有大量的 client 同時向 server 發出請求,那麼此時 server 就會需要建立大量的 socket 連線。但在一個系統當中,往往需要限制單個 server 程式所能使用的最大 socket 數,以供其他的 server 程式所使用。那麼我們如何來做到這一點呢?答案是我們可以通過 ulimit 來實現!細心的讀者可能會發現,通過前面章節的介紹似乎沒有限制 socket 使用的 ulimit 選項。是的,ulimit 並沒有哪個選項直接說是用來限制 socket 的數量的。但是,我們有 -n 這個選項,它是用於限制一個程式所能開啟的檔案描述符的最大值。在 Linux 下一切資源皆檔案,普通檔案是檔案,磁碟印表機是檔案,socket 當然也是檔案。在 Linux 下建立一個新的 socket 連線,實際上就是建立一個新的檔案描述符。如下圖所示(檢視某個程式當前開啟的檔案描述符資訊):
圖 7. 檢視程式開啟檔案描述符
因此,我們可以通過使用 ulimit – n 來限制程式所能開啟的最大檔案描述符數量,從而達到限制 socket 建立的數量。
使用 ulimit 限制 shell 多執行緒程式堆疊的大小(增加可用執行緒數量)
在最後一個例子中,向大家介紹如何使用 -s(單位 KB)來對執行緒的堆疊大小進行限制,從而減少整個多執行緒程式的記憶體使用,增加可用執行緒的數量。這個例子取自於一個真實的案例。我們所遇到的問題是系統對我們的多執行緒程式有如下的限制:
ulimit -v 200000
根據本文前面的介紹,這意味著我們的程式最多隻能使用不到 200MB 的虛擬記憶體。由於我們的程式是一個多執行緒程式,程式在執行時會根據需要建立新的執行緒,這勢必會增加總的記憶體需求量。一開始我們對堆疊大小的限制是 1024 (本例子中使用 1232 來說明):
# ulimit – s 1232
當我們的程式啟動後,通過 pmap 來檢視其記憶體使用情況,可以看到多個佔用 1232KB 的資料段,這些就是程式所建立的執行緒所使用的堆疊:
圖 8. 程式執行緒所使用的堆疊
每當一個新的執行緒被建立時都需要新分配一段大小為 1232KB 的記憶體空間,而我們總的虛擬記憶體限制是 200MB,所以如果我們需要建立更多的執行緒,那麼一個可以改進的方法就是減少每個執行緒的固定堆疊大小,這可以通過 ulimit – s 來實現:
# ulimit -s 512
我們將堆疊大小設定為 512KB,這時再通過 pmap 檢視一下我們的設定是否起作用:
圖 9. 設定 ulimit 後堆疊大小
從上面的資訊可以看出,我們已經成功的將執行緒的堆疊大小改為 512KB 了,這樣在總記憶體使用限制不變的情況下,我們可以通過本小節介紹的方法來增加可以建立的執行緒數,從而達到改善程式的多執行緒效能。
相關文章
- Linux ulimit使用LinuxMIT
- ulimit操作及使用MIT
- 【CentOS7】ulimit 使用CentOSMIT
- Linux下ulimit、find命令使用者LinuxMIT
- ulimit詳解MIT
- aix中使用者ulimit 限制的解決AIMIT
- [效能]ulimit與systemtapMIT
- Linux下ulimit命令的詳細使用介紹LinuxMIT
- Ubuntu 永久修改 ulimit -nUbuntuMIT
- linux----ulimit 限制LinuxMIT
- linux ulimit設定LinuxMIT
- linux_ulimit_open filerLinuxMIT
- 【LINUX】linux ulimit調優LinuxMIT
- 透過 ulimit 改善系統效能MIT
- linux/unix ulimit命令詳解LinuxMIT
- Solaris 10’s Resource Management and Shell Limit(ulimit)MIT
- ulimit限制導致的 +++ killed by SIGKILL +++MIT
- 關於 ulimit 的兩個天坑MIT
- ulimit: core file size: cannot modify limit: Operation not permittedMIT
- Linux 指令篇:系統設定--ulimitLinuxMIT
- -bash: ulimit: open files: cannot modify limit: Operation not permittedMIT
- 關於 CentOS 7 裡面 普通使用者 Ulimit max user processes 值的問題CentOSMIT
- 如何在 Linux 伺服器上設定 ulimit 和檔案描述符數限制Linux伺服器MIT
- 在Linux中,umask 和 ulimit有什麼區別?LinuxMIT
- 452 Error writing file: A file cannot be larger than the value set by ulimit.ErrorMIT
- Mysql報Too many connections,不要亂用ulimit了,看看如何正確修改程式的最大檔案數MySqlMIT
- suse linux 10_su - oracle報ulimit錯誤-cannot modify limit:LinuxOracleMIT
- -bash: ulimit: max user processes: cannot modify limit: Operation not permitted問題的處理MIT
- 如何使用GitHub?Github
- 如何使用 DockerHubDocker
- 如何使用MyBatisMyBatis
- 如何使用反射反射
- MQTT如何使用MQQT
- 如何使用 Service 模式模式
- PostMan該如何使用Postman
- 如何使用go文件Go
- WebBits庫如何使用Web
- 如何使用htmltab庫HTML