コードを見た後(不当な利点)、主な問題は、パイプを完全に閉じないことと組み合わされたプロセス構造でした。
パイプラインのプロセス構造ps | sort
は次のとおりです。
main shell
- coordinator sub-shell
- ps
- sort
メインシェルはN本のパイプを作成していました(N = 1の場合ps | sort
)。次に、コーディネーターシェルが作成されました。N+1の子を開始します。しかし、彼らが終了するのを待たず、パイプのコピーを閉じませんでした。また、メインシェルはパイプのコピーを閉じませんでした。
より通常のプロセス構造は、おそらくコーディネーターサブシェルなしで実行されます。子を生成するための2つのメカニズムがあります。従来、メインシェルは1つのサブプロセスをフォークしていました。パイプラインの最初のN個のプロセスの調整を行い(最初にパイプを作成することを含む)、次にパイプラインの最後のプロセスを実行します。メインシェルは1つの子が終了するのを待ち、パイプラインの終了ステータスは子の終了ステータス(パイプラインの最後のプロセス)です。
最近でbash
は、メインシェルがパイプライン内の各子のステータスを取得するメカニズムを提供しています。それは調整を行います。
主な修正(主にマイナーなコンパイル警告を除く)は次のとおりです。
- コーディネーターをフォークした後、メインシェルはすべてのパイプを閉じます。
- メインシェルは、コーディネーターが完了するのを待ちます。
- コーディネーターは、パイプラインをフォークした後、すべてのパイプを閉じます。
- コーディネーターは、パイプライン内のすべてのプロセスが完了するのを待ちます。
- コーディネーターが終了します(決闘のデュアルプロンプトを提供するために戻る代わりに)。
より良い修正は、コーディネーターサブシェルを排除します(これは、説明されている従来のシステムのように動作します)。