새로 시작된 bash에서 (이전 하위 프로세스 없이) 다음 명령을 실행합니다.
$ prlimit --pid $BASHPID --nproc=20:
이것은 나에게 눈사태를 주었다
bash: fork: retry: No child processes
bash: fork: retry: No child processes
bash: fork: retry: No child processes
bash: fork: retry: No child processes
bash: fork: Resource temporarily unavailable
20이 너무 낮은지, 아니면 프로그램 오류인지 알고 싶습니다. 여기서 무슨 일이 일어나고 있는 걸까요?
Bash에 내부 ulimit
호출이 내장되어 있다는 것을 알고 있는데 왜 prlimit
작동하지 않나요?
고쳐 쓰다#
bash 내장 함수도 ulimit
동일한 결과를 생성합니다.
$ ulimit -Su 20
bash: fork: retry: No child processes
bash: fork: retry: No child processes
bash: fork: retry: No child processes
bash: fork: retry: No child processes
bash: fork: Resource temporarily unavailable
bash: wait_for: No record of process 7527
bash: fork: retry: No child processes
bash: fork: retry: No child processes
이 질문에 대한 대답은 ulimit RLIMIT_NPROC를 이해하는 방법과 관련이 있을 수 있습니다. UID와 PID가 모두 바인딩된 것 같나요?
어쩌면 누군가가 두 가지 다른 오류 메시지를 구별하는 방법을 밝힐 수도 있습니다 No child processes
.Resource temporarily unavailable
답변1
프로세스 제한이 어떻게 작동하는지 오해하고 있습니다. prlimit --nproc
일명 전체 사용자에 대한 최대 프로세스 수 RLIMIT_NPROC
입니다 . ulimit -u
이미 20개의 실행 중인 프로세스가 있고 제한을 20으로 설정한 경우 새 프로세스를 생성할 수 없습니다. 중요한 것은 사용자로 실행 중인 프로세스 수이며, 상위 프로세스가 누구인지 또는 제한 설정이 무엇인지는 중요하지 않습니다.
미묘한 점은 제한이 전역적이지만 이를 설정하는 프로세스에만 적용된다는 것입니다. 따라서 18개의 프로세스가 실행 중이고 prlimit --nproc 20 bash
하나의 터미널과 다른 터미널에서 prlimit --nproc 30 bash
첫 번째 bash는 하위 프로세스를 생성할 수 없지만 두 번째 bash는 더 많은 하위 프로세스를 생성할 수 있습니다(활성화 여부에 관계없이). 그 난교든 아니든).
프로세스 제한을 1로 설정하면 해당 프로세스는 전혀 분기할 수 없지만 다른 프로세스는 여전히 분기할 수 있습니다. 로그인 스크립트에서 제한을 숫자로 설정하면 해당 숫자가 프로세스에 적용됩니다(cron 작업에서 시작된 프로세스와 같이 로그인 스크립트를 읽지 않고 시작된 프로세스는 제외). 다른 상황에서는 혼란스러울 수 있습니다.
구현 관점에서 이를 설명하는 것이 가장 쉽습니다. 이 제한은 시스템 호출을 실행할 때만 읽혀집니다 fork
. 프로세스가 호출하면 fork
커널은오른쪽프로세스는 동일한 사용자로 실행됩니다. 호출 프로세스의 NPROC 제한이 다음보다 작거나 같은 경우오른쪽그런 다음 오류 EAGAIN
("리소스를 일시적으로 사용할 수 없습니다", 즉 "재시도")와 함께 호출이 거부됩니다.
귀하의 경우에는 이미 20개 이상의 프로세스가 실행 중이고 .bashrc
여러 개의 하위 프로세스가 실행 중일 것입니다(또는 프로세스 제한에 도달하여 실행할 수 없습니다).
오류가 있을 때 bash는 여러 번 포크를 시도하기 때문에 두 가지 다른 메시지가 표시됩니다 EAGAIN
. 처음에는 재시도 중이라는 메시지가 표시되고 마지막에는 포기했다는 메시지가 표시됩니다.
더 정확하게 말하면 커널 스레드입니다.
²이 시스템 호출은 Linux에서 호출됩니다 clone
.
답변2
결론은 -nproc
실행 가능한 프로젝트(예: 스레드 및 프로세스)의 제한을 설정하는 것입니다. 그리고 부풀어 오른 .bashrc 콘텐츠로 인해 20개 이상의 스레드가 필요합니다. 적어도 그것이 내 가정입니다.
이와 같이 새로운 bash를 시작한 후
$ bash --noprofile --norc
이것은 가능하다
bash-4.3$ ulimit -Su 1
bash-4.3$ echo 1
1
bash-4.3# echo 1 &
bash: fork: retry: No child processes
스레드 하나면 충분합니다. 와!