Linux에서 프로세스 당 최대 스레드 수?


245

Linux에서 프로세스로 작성할 수있는 최대 스레드 수는 얼마입니까?

이 값을 어떻게 (가능하다면) 수정할 수 있습니까?

답변:


247

Linux에는 프로세스 당 별도의 스레드가 없으며 시스템의 총 프로세스 수에 대한 제한 (스레드는 기본적으로 Linux의 공유 주소 공간이있는 프로세스)으로 다음과 같이 볼 수 있습니다.

cat /proc/sys/kernel/threads-max

기본값은 메모리 페이지 수 / 4입니다. 이것을 다음과 같이 늘릴 수 있습니다.

echo 100000 > /proc/sys/kernel/threads-max

단일 사용자가 만들 수있는 프로세스 수 (따라서 스레드)에도 ulimit/getrlimit제한이 있습니다. 이러한 제한에 대한 자세한 내용을 참조하십시오 .


3
/ proc / sys / vm / max_map_count의 제한도 스레드 수를 제한 할 수 있습니다. 당신이 그것을 칠 경우 그 한계를 많이 증가시키는 것이 안전해야합니다.
Mikko Rantalainen

1
Robert : Linux는 프로세스 당 제한을 간접적으로 구현합니다. 자세한 내용은 내 대답을 확인)
codersofthedark

우분투 12.04에서 이것을 변경하려고하는데 명령으로 변경되지 않습니다. 또한 vi를 변경하려고 시도했지만 vi E667: Fsync failed를 저장하려고하면 얻을 수 있습니다.
Siddharth

4
@dragosrsupercool 최대 스레드는 전체 RAM을 사용하여, 가상 메모리를 계산되지
c4f4t0r

1
스레드 당 스택 크기의 양 (시스템의 기본값)이 다른 것보다 더 제한적일 수 있습니다. 스레드 당 스택 크기를 줄이는 것은 총 스레드 수를 늘리는 방법입니다 (좋은 생각은 아니지만).
랜디 하워드

67

LINUX에 프로세스 제한 당 별도의 스레드가 없다고 말하는 것은 잘못된 것입니다.

리눅스는 프로세스 당 최대 스레드 수를 간접적으로 구현합니다 !!

number of threads = total virtual memory / (stack size*1024*1024)

따라서 전체 가상 메모리를 늘리거나 스택 크기를 줄이면 프로세스 당 스레드 수를 늘릴 수 있습니다. 그러나 스택 크기를 너무 줄이면 스택 오버플로로 인해 코드 오류가 발생할 수 있으며 최대 가상 메모리는 스왑 메모리와 같습니다.

기계 점검 :

총 가상 메모리 : ulimit -v(기본값은 무제한이므로이를 늘리려면 스왑 메모리를 늘려야합니다)

총 스택 크기 : ulimit -s(기본값은 8Mb)

이 값을 늘리는 명령 :

ulimit -s newvalue

ulimit -v newvalue

* 새 값을 한계로 설정하려는 값으로 바꾸십시오.

참고 문헌 :

http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/


11
세가지 작은 세부 사항을 제외하고 : 1. 리눅스는 이것을하지 않으며, 스택의 존재와 메모리와 주소 공간이 유한 한 크기라는 사실은 그것과 아무 관련이 없습니다. 스레드 생성시 스레드 스택을 지정해야합니다 ulimit -s. 가능한 스레드 ID가있는 한 많은 스레드를 작성하는 것이 가능합니다. 64 비트 리눅스에서는 스레드 ID보다 더 많은 스레드를 생성하는 것이 "가능하다"(물론 불가능하지만 스택이 진행되는 한). 3. 스택 예약, 커밋 및 VM은 OC와는 다른 것입니다.
데이먼

예, 스레드 수를 늘리려면 가상 메모리를 늘리거나 스택 크기를 줄여야합니다. Raspberry Pi에서 스택 크기를 기본 8MB에서 1MB로 줄이면 가상 메모리를 늘리는 방법을 찾지 못했습니다. 프로세스 당 1000 개가 넘는 스레드를 얻을 수 있지만“ulimit -s”명령으로 스택 크기를 줄일 수 있습니다 모든 스레드에 대해이 작업을 수행하십시오. 따라서 pthread_t를 사용하여 각 스레드 당 스택 크기를 설정할 수 있기 때문에 내 솔루션은 "pthread_t"인스턴스 "thread class"를 사용했습니다. 마지막으로, 각각 1MB의 스택을 가진 각 라즈베리 파이에서 프로세스 당 1000 개 이상의 스레드를 아카이브 할 수 있습니다
Deulis

43

실제적으로 한계는 일반적으로 스택 공간에 의해 결정됩니다. 각 스레드가 1MB 스택을 얻는다면 (Linux에서 기본값인지 기억할 수 없습니다), 3000 비트 후에 32 비트 시스템의 주소 공간이 부족합니다 (마지막 gb가 커널에 예약되어 있다고 가정) .

그러나 수십 개 이상의 스레드를 사용하면 성능이 크게 저하 될 수 있습니다. 조만간 너무 많은 컨텍스트 전환 오버 헤드, 스케줄러의 오버 헤드 등이 발생합니다. (많은 스레드를 생성하는 것은 많은 메모리를 소비하는 것 이상은 아닙니다. 그러나 실제 작업 을 수행 하는 많은 스레드 는 사용 가능한 CPU 시간 동안 싸우면서 속도가 느려집니다)

이 한도와 관련하여 무엇을하고 있습니까?


3
스택 당 스레드 당 1MB는 ​​상당히 높기 때문에 많은 프로그램이 이처럼 많은 스택 공간 근처에 필요하지 않습니다. 성능은 존재하는 스레드 수가 아닌 실행 가능한 프로세스 수를 기반으로 합니다. 나는 0.40의 하중을 가진 1200+ 스레드로 지금 실행중인 머신을 가지고 있습니다.
Robert Gamble

13
스레드 성능에 따라 성능이 달라집니다. 그들이하지 않고 컨텍스트 전환이 적다면 수십보다 훨씬 더 높아질 수 있습니다.
Corey Goldberg

스택은 동적으로 성장하고, 단지 초기 페이지가 - 더 - 박쥐 할당
마이클 판 코프

28

리눅스에서 적절한 100k 스레드 :

ulimit -s  256
ulimit -i  120000
echo 120000 > /proc/sys/kernel/threads-max
echo 600000 > /proc/sys/vm/max_map_count
echo 200000 > /proc/sys/kernel/pid_max 

 ./100k-pthread-create-app

시스템 시스템에서 @Thomas의 2018 업데이트 :

/etc/systemd/logind.conf: UserTasksMax=100000

4
감사합니다. 마침내 32k Java 스레드 수를 뚫을 수있었습니다.
berezovskyi

1
나를 위해 작동하지 않습니다 : $ ulimit -s 100000 $ ulimit -i 63645 $ cat / proc / sys / kernel / threads-max 127626 $ cat / proc / sys / vm / max_map_count 600000 $ cat / proc / sys / kernel / pid_max 200000 $ java -Xmx4G -Xss256k -cp. ThreadCreation ... 11542 11543 java.lang.OutOfMemoryError : java.lang.Thread.start0 (네이티브 메소드)에서 java.lang.Thread.start (Thread.java:717)의 ThreadCreation.main ( ThreadCreation.java:15)
Martin Vysny

@MartinVysny ulimit -s = KB 단위의 스레드 크기. 100MB 스레드 스택 크기의 스레드를 만들려고합니다.
블라디미르 Kunschikov

@Thomas를 확인하지 않고 의견을 추가했습니다.
블라디미르 Kunschikov

2
@ VladimirKunschikov 감사합니다 친구, 솔루션이 실제로 효과가 있었고 Thomas에게 추가 라인을 추가해 주셔서 감사합니다. 해당 라인이 작동하지 않는다는 것을 확인할 수 있습니다.
BillHoo

14

@dragosrsupercool

Linux는 가상 메모리를 사용하여 최대 스레드 수를 계산하지 않지만 시스템에 설치된 실제 램

 max_threads = totalram_pages / (8 * 8192 / 4096);

http://kavassalis.com/2011/03/linux-and-the-maximum-number-of-processes-threads/

커널 / 포크

/* The default maximum number of threads is set to a safe
 * value: the thread structures can take up at most half
 * of memory.
 */
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);

따라서 설치된 램의 크기가 다를 수 있기 때문에 스레드 최대는 모든 시스템마다 다릅니다 .Linux는 가상 메모리를 늘릴 필요가 없다는 것을 알고 있습니다 .32 비트에서는 사용자 공간에 3GB, 커널에 1GB가 있으므로 64 비트에서 128TB의 가상 메모리를 얻었습니다. Solaris에서 발생합니다. 가상 메모리를 늘리려면 스왑 공간을 추가해야합니다.


11

검색하려면 다음을 수행하십시오.

cat /proc/sys/kernel/threads-max

설정하려면

echo 123456789 > /proc/sys/kernel/threads-max

123456789 = 스레드 수


루트로도 쓰기를 시도 할 때 권한이 거부되었습니다.
Kim

글이 게시 된 지 거의 10 년이 지났습니다. ... 나는 문제의 현재 상태에 대한 최신 아니지만, 많은 변화 (아마도이) 수도
빈센트 반 덴 Berghe

perm-deny 관련 문제가 추가 될 수 있습니다 ( >) 부분이 손실 됨 sudo: tryecho 12345678 | sudo tee -a /proc/sys/kernel/threads-max
dwanderson

10

스레드 수 제한 :

$ cat /proc/sys/kernel/threads-max 

계산 방법 :

max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);

x86_64 페이지 크기 (PAGE_SIZE)는 4K입니다. 다른 모든 아키텍처와 마찬가지로 x86_64에는 모든 활성 스레드에 대한 커널 스택이 있습니다. 이 스레드 스택은 THREAD_SIZE (2 * PAGE_SIZE)입니다.

mempages의 경우 :

cat /proc/zoneinfo | grep spanned | awk '{totalpages=totalpages+$2} END {print totalpages}';

실제로 숫자는 스레드 메모리 스택 크기 제한과 관련이 없습니다.ulimit -s )의 .

추신 : 스레드 메모리 스택 제한은 rhel VM에서 10M이며 1.5G 메모리의 경우이 VM은 150 스레드 만 감당할 수 있습니까?


5

시스템 시스템 (특히 필자의 경우 우분투 16.04)에서 이것을보고있는 사람에게는 cgroup pids.max 매개 변수에 의해 적용되는 또 다른 제한이 있습니다.

기본적으로 12,288로 설정되어 있으며 /etc/systemd/logind.conf에서 재정의 할 수 있습니다.

pids_max, threads-max, max_maps_count, ulimits 등을 포함한 다른 조언이 여전히 적용됩니다.


5

내 경우 Redhat Linux 2.6에서 ulimit를 사용하여 스레드 당 스택 크기를 확인하십시오.

    ulimit -a
...
    stack size              (kbytes, -s) 10240

각 스레드는 스택에 할당 된이 메모리 양 (10MB)을 가져옵니다. 32 비트 프로그램과 최대 주소 공간 4GB를 사용하면 최대 4096MB / 10MB = 409 스레드입니다 !!! 마이너스 프로그램 코드, 마이너스 힙 공간은 아마도 최대 값으로 이어질 것입니다. 300 개의 스레드.

64 비트에서 컴파일 및 실행하거나 ulimit -s 8192 또는 ulimit -s 4096을 설정하여이 값을 올릴 수 있어야합니다. 그러나 이것이 바람직하다면 다른 토론입니다 ...


4

아마 중요하지 않을 것입니다. 고정 된 수의 스레드 (예 : 4 개 또는 8 개의 프로세서가있는 경우 4 또는 8)를 사용하도록 알고리즘을 설계하면 성능이 훨씬 향상됩니다. 작업 대기열, 비동기 IO 또는 libevent와 같은 작업으로이를 수행 할 수 있습니다.


3
멀티 스레딩의 목적은 성능 만이 아닙니다. 예를 들어 4 개의 코어 프로세서에서 차단 시스템이있는 10 개의 포트를 수신하고 있습니다. 이 예에서는 4의 의미가 없습니다.
obayhan

3

nbio 블록을 차단하는 I / O 호출을 위해 더 많은 스레드가 필요한 경우 비 차단 I / O 라이브러리 등을 사용하십시오.


2

시스템에 따라, 루프에서 프로세스를 작성하여 샘플 프로그램을 작성하고 ps axo pid, ppid, rss, vsz, nlwp, cmd를 사용하여 확인하십시오. 더 이상 스레드를 만들 수없는 경우 nlwp count [nlwp is number threads] voila를 확인하십시오.


1

영구적으로 설정하려면

vim /etc/sysctl.conf

그리고 추가

kernel.threads-max = "value"

0

리눅스에서 다음 파일에 정의 된 최대 스레드 수를 볼 수 있습니다

고양이 / proc / sys / kernel / threads-max

(또는)

sysctl -a | 그렙 스레드 최대


0

다음 명령으로 현재 값을 볼 수 있습니다-cat / proc / sys / kernel / threads-max

당신은 또한 같은 값을 설정할 수 있습니다

echo 100500> / proc / sys / kernel / threads-max

설정 한 값은 사용 가능한 RAM 페이지와 비교하여 확인됩니다. 스레드 구조가 사용 가능한 RAM 페이지의 1/8 이상을 차지하면 그에 따라 thread-max가 줄어 듭니다.


0

예, 스레드 수를 늘리려면 가상 메모리를 늘리거나 스택 크기를 줄여야합니다. Raspberry Pi에서는 스택 크기를 기본 8MB에서 1MB로 줄이면 가상 메모리를 늘리는 방법을 찾지 못했습니다. 프로세스 당 1000 개가 넘는 스레드를 얻을 수 있지만“ulimit -s”명령으로 스택 크기를 줄일 수 있습니다 모든 스레드에 대해이 작업을 수행하십시오. 따라서 pthread_t를 사용하여 각 스레드 당 스택 크기를 설정할 수 있기 때문에 내 솔루션은 "pthread_t"인스턴스 "thread class"를 사용했습니다. 마지막으로, 프로세스 당 1000 개 이상의 스레드를 Raspberry Pi에서 각각 1MB의 스택으로 보관할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.