修正する#

修正する#

新しく開始された 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の両方がバインドされていると思いますか?

たぶん、誰かが2つの異なるエラーメッセージを区別する方法を明らかにするかもしれませんNo child processesResource temporarily unavailable

答え1

プロセス制限がどのように機能するかを誤解しています。prlimit --nproc別名ユーザー全体のプロセスの最大数RLIMIT_NPROCulimit -uすでに20個の実行中のプロセスがあり、制限を20に設定している場合は、新しいプロセスを作成できません。重要なのは、ユーザーとして実行されているプロセスの数であり、親プロセスが誰であるか制限設定が何であるかは重要ではありません。

微妙な点は、制限はグローバルですが、これを設定するプロセスにのみ適用されることです。したがって、18個のプロセスが実行されており、1つの端末と別の端末prlimit --nproc 20 bashで、最初prlimit --nproc 30 bashのbashは子プロセスを作成できませんが、2番目のbashはより多くの子プロセスを生成できます(アクティブかどうかにかかわらず)。その乱交かどうか)。

プロセス制限を1に設定すると、そのプロセスはまったく分岐できませんが、他のプロセスはまだ分岐できます。ログインスクリプトで制限を数値に設定すると、その番号がプロセスに適用されます(cronジョブで開始されたプロセスなど、ログインスクリプトを読み取らずに起動されたプロセスを除く)。他の状況では混乱する可能性があります。

実装の観点からこれを説明するのが最も簡単です。この制限は、システムコールを実行したときにのみ読み取られますfork。プロセスが呼び出されると、forkカーネルはプロセスは同じユーザーとして実行されます。呼び出しプロセスの NPROC 制限が次以下の場合その後、エラーEAGAIN(「リソースを一時的に使用できません」、つまり「再試行」)で呼び出しが拒否されます。

あなたの場合、すでに20以上のプロセスが実行されており、.bashrc複数の子プロセスが実行されている(またはプロセス制限に達して実行することはできません)。

エラーが発生すると、bashは何度もフォークを試みるため、2つの異なるメッセージが表示されます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

スレッド一つで十分です。うわー!

関連情報