新しく開始された 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 processes
。Resource temporarily unavailable
答え1
プロセス制限がどのように機能するかを誤解しています。prlimit --nproc
別名ユーザー全体のプロセスの最大数RLIMIT_NPROC
。ulimit -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
スレッド一つで十分です。うわー!