この無限ループがシステムリソースを消費しないのはなぜですか?

この無限ループがシステムリソースを消費しないのはなぜですか?

BASHで次のことを行いました。

while true;do bash;done

私はこの行を書きましたが、最初はそれが正しいかどうかはわかりませんでした:

  • メモリが不足している場合は、メインシェルに留まり、できるだけ多くのサブシェルを作成してください。
  • メインシェルはサブシェルを作成し、リネージュにメモリが不足するまでサブシェルを作成します。

しかし、ライナーを実行すると、シャットダウンと別のシャットダウンと別のシャットダウンとシャットダウン、シャットダウン、シャットダウンを入力し始めるため、これが2番目のケースのようです。ただし、プロンプトの直後はまだメインシェルに戻りません。戻る。

今、あまりにも多くのサブシェルが開いていて、各サブシェルがプログラムなので、各サブシェルには固有のPIDが必要であると思いました。

だから私はこれをしました:

ps aux | grep bash

名前にbashを含むプロセスがたくさんあると予想されます。

しかし、そのようなものはなく、2つのbashシェルしかありません。

どうすれば可能ですか?私はプロセス、シェル、サブシェル、PIDについて非常に間違った考えを持っていますが、どこにいるのかわかりません。

答え1

ループは、各反復で対話型シェルセッションを開始します。

対話型セッションはヒントを提供します(対話型であるため)。終了すると、ループの制御が返され、他の対話型シェルが起動します。

そのため、一度に多くのプロセスを取得せずにbash2つのプロセス、つまりループを実行する親プロセスと新しいプロンプトを提供する子プロセスのみを取得します。


ループは次のように書くこともできます。

while true; do bash; done

このtrueユーティリティは引数を使用せず、単にゼロ終了値を返します。これはシェルで「true」と解釈されます。


bash爆発するプロセス(いわゆる「フォーク爆弾」)が必要な場合は、次のように書きました。

while true; do { bash & }; done

bashこれにより、ループが繰り返されるたびにインタラクティブセッションが開始されますが、バックステージコース。セッションはバックグラウンドプロセスで始まるため、ループはbash次のプロセスを開始する前に最新のプロセスが完了するのを待ちません。

回復するには、システムを再起動する必要があります。

このフォーク爆弾は始まったばかりだから、思ったより軽い。一つ繰り返しごとに新しいプロセス。他の人は指数関数的にプロセスを開始する可能性が高いです。

答え2

あなたのループは多数のシェルを実行しますが、並列ではなく1つずつ実行されます。ループが初めて実行されると、新しいbashシェルが起動し、プロンプトが表示されます。親シェルは、シェルが終了するのを待ちます。exitこれは、入力して子シェルを終了して親シェルに戻ると発生します。親シェルはループを繰り返して再度実行され、新しいbashシェルを起動してプロンプトを表示します。

以下を実行してシェルレベルを表示できます。

echo $SHLVL

コマンドを入力し続けても、この数字は変わりませんexit

関連情報