有名なことを経験したフォーク爆弾の問題Askubuntuや他の多くのStack Exchangeサイトではあまりにも明白であるため、誰もが話していることをよく理解していません。
多くの答え(最高の例)こう言います。
「は、
{:|: &}
関数を実行して:
出力を:
関数に送り返すことを意味します。」
素晴らしい、正確には何ですか?出力は:
?相手にどんな内容が伝わっていますか:
?
そして:
本質的に自分自身を呼び出す関数を生成しています。二重呼び出すたびにそれ自体で終了するメソッドはありません。
どのように実装されますか?二重?私が見るには、:
最初の実行が完了する:
まで2番目の実行には何も渡されないようです。実行は実際には終了しません。
たとえばC
、
foo()
{
foo();
foo(); // never executed
}
2番目はfoo()
まったく実行されません。単に最初はfoo()
終わらないからです。
私は同じロジックが適用されると思います:(){ :|: & };:
。
:(){ : & };:
同じことをしなさい
:(){ :|: & };:
論理を理解するのに役立ちます。
答え1
パイプラインでは、別のインスタンスを起動する前に最初のインスタンスを完了する必要はありません。実際に行うことはリダイレクトだけです。標準出力最初のケース標準入力2つ目は、同時に実行できるようにすることです(フォーク爆弾が作動しなければならないからです)。
もしそうなら、その出力は正確に何ですか
:
?相手に何が伝わっていますか:
?
':' は他の ':' インスタンスに何も書かず、リダイレクトのみします。標準出力到着標準入力の2番目のインスタンスです。もし実行中に何かを書いて(自己フォークだけを実行するので絶対に実行しない)、次に進みます。標準入力別のケース。
想像するのに役立つ標準入力そして標準出力群れとして:
何と書かれていても標準入力プログラムが読み取りとして決定するときに使用するためにスタックされます。標準出力同じように動作します。必要に応じて他のプログラムが読み取れるように複数のプログラムに書き込みます。
これにより、通信が発生しないパイプ(2つの空のヒープ)や非同期の書き込みと読み取りなどの状況を簡単に想像できます。
正確にどのように2回実行されますか?私が見るには、
:
最初の実行が完了する:
まで2番目の実行には何も渡されないようです。実行は実際には終了しません。
インスタンスの入力と出力をリダイレクトするので、2番目のインスタンスが起動する前に最初のインスタンスを完了する必要はありません。実際には、通常、2つが同時に実行され、2つ目が最初のものがすぐに解析されるデータを処理できるようにしたいです。これがここで起こるものです。どちらも最初の操作が完了するのを待たずに呼び出されます。これはすべてに適用されます。パイプチェーンコマンドライン。
私は同じロジックが :(){ :|: & };: にも当てはまると思います。
:(){ : & };:
同じことをしなさい
:(){ :|: & };:
1つ目は、関数自体が再帰的に実行されてもバックグラウンド(: &
)で呼び出されるため、機能しません。最初のインスタンスは、セルフシャットダウン前に:
「サブ」が返されるのを待たないため、実行中のインスタンスは:
1つしか残りません:
。あなたがそれを持っているならば、最初は「子供」が戻るのを待ち、自分の「子」が戻るのを待つので、うまくいきます:(){ : };:
。:
:
:
実行中のインスタンス数に応じたさまざまなコマンドの外観は次のとおりです。
:(){ : & };:
1つのインスタンス(呼び出し:
と終了) - > 1つのインスタンス(呼び出しと終了:
) - > 1つのインスタンス(呼び出し:
と終了) - > 1つのインスタンス - > ...
:(){ :|: &};:
1インスタンス(それぞれ2を呼び出し:
て終了) - > 2インスタンス(それぞれ2を呼び出して終了:
) - > 4インスタンス(各インスタンスが2を呼び出し:
て終了) - > 8インスタンス - > ...
:(){ : };:
1つのインスタンス(呼び出して戻りを待って:
います) - > 2つのインスタンス(子供が別のインスタンスを呼び出して戻りを待っています:
) - > 3つのインスタンス(子供が別のインスタンスを呼び出して:
戻りを待っています) - > 4個のインスタンス - > 。 ..
:(){ :|: };:
1つのインスタンス(2つを呼び出し:
てリターンを待っている間) - > 3つのインスタンス(:
各2つを呼び出してリターンを待つ子供) - > 7つのインスタンス(:
2つを呼び出してリターンを待つ子) - > 15犬のインスタンス - > ...
ご覧のとおり、バックグラウンドで(forkを使用して&
)関数を呼び出すと、呼び出された関数が返される前に被呼者が終了するため、実際にフォーク爆弾が遅くなります。