Linuxでのパイプの仕組み


25

Linuxカーネルにパイプがどのように実装されているかを読んでいて、私の理解を検証したかったのです。私が間違っている場合は、正しい説明の答えが選択されます。

  • Linuxには(ユーザー空間ではなく)カーネルにマウントされるpipefsと呼ばれるVFSがあります
  • pipefsには単一のスーパーブロックがあり、独自のルート(pipe:)にマウントされます。/
  • ほとんどのファイルシステムとは異なり、pipefsは直接表示できません
  • pipefsへのエントリはpipe(2)syscall 経由です
  • pipe(2)配管用のシェルが使用するシステムコール|オペレータ(または手動で任意の他のプロセスからは)ほとんど通常のファイルと同じように動作しpipefsに新しいファイルを作成します
  • パイプオペレーターの左側のstdoutファイルは、pipefsで作成された一時ファイルにリダイレクトされます。
  • パイプ演算子の右側のファイルには、stdinpipefs上のファイルが設定されています。
  • pipefsはメモリに格納されており、いくつかのカーネルマジックによってページングされるべきではありません

パイプ(例ls -la | less)がどのように機能するかについてのこの説明はほとんど正しいですか?

私が理解していないことの1つは、bashのようなものがどのようにプロセスを設定するstdinstdout、またはによって返されるファイル記述子に設定することpipe(2)です。私はまだそれについて何も見つけることができませんでした。


同じ名前の2つのかなり異なるレイヤーについて話していることに注意してください。pipe()機械それがサポートしていることを(一緒にカーネルの呼び出しpipefsなど)よりもはるかに低いレベルである|シェルで提供事業者。後者は通常前者を使用して実装されますが、そうである必要はありません。
グレッグヒューギル14

はい、私は具体的に低レベルの操作について言及していますが、|オペレーターはpipe(2)bashのようにプロセスとして呼び出しているだけであるという前提で。
ブランドンワンボルト14

回答:


19

これまでの分析は一般的に正しいです。シェルがプロセスの標準入力をパイプ記述子に設定する方法は(擬似コード)です。

pipe(p) // create a new pipe with two handles p[0] and p[1]
fork() // spawn a child process
    close(p[0]) // close the write end of the pipe in the child
    dup2(p[1], 0) // duplicate the pipe descriptor on top of fd 0 (stdin)
    close(p[1]) // close the other pipe descriptor
    exec() // run a new process with the new descriptors in place

ありがとう!なぜdup2呼び出しが必要なのか興味があり、パイプ記述子を標準入力に直接割り当てることはできませんか?
ブランドンワンボルト14

3
呼び出し側は、ファイル記述子の作成時にファイル記述子の数値を選択することはできませんpipe()。このdup2()呼び出しにより、呼び出し元はファイル記述子を特定の数値にコピーできます(0、1、2はstdin、stdout、stderrであるため必要です)。これは、「stdinに直接割り当てる」ことと同等のカーネルです。Cランタイムライブラリのグローバル変数stdinはa FILE *であり、カーネル関連ではないことに注意してください(ただし、記述子0に接続されるように初期化されます)。
グレッグヒューギル14

素晴らしい答えです!詳細については少し迷っています。exec()を実行する前になぜclose(p [1])を実行するのか不思議に思っていますか?dup2が戻ったら、p [1]はfd 0を指していませんか?次に、close(p [1])はファイル記述子0を閉じます。それでは、子プロセスの標準入力からどのように読み取ることができますか?
user1559897

@ user1559897:dup2呼び出しは変更されませんp[1]。代わりに、2つのハンドルp[1]を作成0し、同じカーネルオブジェクト(パイプ)を指します。子プロセスは2つのstdinハンドルを必要としないため(p[1]とにかく番号付けされたハンドルが何であるかを知りません)、のp[1]前に閉じられexecます。
グレッグヒューギル

@GregHewgillゴッチュ。THX!
user1559897
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.