1. 程式人生 > >關於linux系統最大程序數和單程序最大執行緒數的測試

關於linux系統最大程序數和單程序最大執行緒數的測試

我的系統:RedHat企業7 64位 記憶體6G
ulimit -a檢視用於shell啟動程序所佔用的資源預設設定
這裡寫圖片描述
一.最大程序數
1.使用命令ulimit -u檢視軟限制,我的為7807
/etc/security/limits.conf檢視硬限制,核心引數kernel.pid_max也做了限制
2.系統用pid_t表示程序號,那麼最大的程序數當然也不能超過pid_t的型別
檢視最大程序數

cat /proc/sys/kernel/pid_max#查系統支援的最大程序數,一般會很大,相當於理論值

這裡寫圖片描述
3.建立一個新程序會消耗系統資源(主要是記憶體),經測試,在建立6000多個程序時,程式執行的很緩慢,通過vmstat

命令看到,swap記憶體置入置出頻繁,可以判斷是由於記憶體不足,使用虛擬記憶體,所建立過多程序時,系統記憶體必須要加以衡量。

程式碼驗證:

#include<iostream>
#include<unistd.h>
#include<stdio.h>
using namespace std;

int main()
{
    pid_t pid;
    int i=0;
    while(1)
    {
        pid = fork();
        if(pid == 0)
            break;
        else
if(pid == -1) { perror("create error"); break; } cout<<i++<<" process"<<endl; } }

這裡寫圖片描述

可以即使是系統的預設配置檔案,對最大程序數還是有所限制的,我的機器最多建立了32012個程序。這也就是為什麼用ps aux命令監控系統資源時,程序的pid達到了近30000.
二.最大執行緒數
/usr/include/bits/local_lim.h#define PTHREAD_THREADS_MAX 1024

,可見最大執行緒數限制為1024,而NPTL( Native POSIX Thread Library)中則沒有硬性的限制,僅受限於系統資源(主要是執行緒的stack所佔用的記憶體,可用命令ulimits -s檢視,一般是8192KB(8M))。

cat /proc/sys/kernel/threads-max #查系統支援的最大執行緒數,一般會很大,相當於理論值

這裡寫圖片描述
程式碼試驗:

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>

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

這裡寫圖片描述
最終結果為32747個,遠遠小於理論值90829
Linux上,最大執行緒數目是:
number of threads = total virtual memory / (stack size*1024*1024),由於我機子的virtual memory為unlimited,,當然。在32位系統上,程序空間是4G,其中0-3G是使用者空間(0x0-0xBFFFFFFF), 3G-4G是核心空間。
因此理論上講,使用者空間大小/棧大小=最大執行緒數。3072M/8M=384,考慮到系統的佔用,主執行緒(管理執行緒)等,應該是在380左右. 也許在你的系統上是382.
我們可以減小棧限制或者增大虛擬記憶體使得執行緒的數目增加。
這裡寫圖片描述

檢查虛擬記憶體: ulimit -v
檢查棧大小:  ulimit -s
設定虛擬記憶體: ulimit -v 新值
設定棧大小: ulimit -s 新值
或者pthread_create用pthread_attr_getstacksize設定一個較小的棧大小

總結系統限制有:
/proc/sys/kernel/pid_max #查系統支援的最大執行緒數,一般會很大,相當於理論值
/proc/sys/kernel/thread-max
max_user_process(ulimit -u) #系統限制某使用者下最多可以執行多少程序或執行緒
/proc/sys/vm/max_map_count硬體記憶體大小(我的為65530)
這裡寫圖片描述

補充

1.查詢當前某程式的執行緒或程序數
pstree -p ps -e | grep java | awk '{print $1}' | wc -l
上面用的是命令替換,關於命令替換,就是說用“括起來的命令會優先執行,然後以其輸出作為其他命令的引數

pstree -p 程序號 | wc -l
top -H 程序號 | wc -l
上面用的是管道,關於管道:管道符號”|”左邊命令的輸出作為右邊命令的輸入
2.查詢當前整個系統已用的執行緒或程序數
pstree -p | wc -l