SIGPIPEはどのような条件で発生しますか?

SIGPIPEはどのような条件で発生しますか?

名前付きパイプがあり、fifo2つの異なるシェルで読み書きしているとします。次の 2 つの例を考えてみましょう。

shell 1$ echo foo > fifo
<hangs>
shell 2$ cat fifo
foo
shell 1$ echo bar > fifo
<hangs>

shell 1$ cat > fifo
<typing> foo
<hangs>
shell 2$ cat fifo
foo
^C
shell 1$
<typing> bar
<exits>

この例で何が起こっているのか、特にパイプに「bar」を書き込もうとすると、最初の例ではブロック呼び出しが発生し、2番目の例ではSIGPIPEがトリガーされる理由を理解できません。

私は最初のケースでは、2つの別々のプロセスがパイプに書き込まれるので2回開かれますが、2番目のケースでは1回だけ開かれ、1つのプロセスによって2回書き込まれ、プロセスがパイプからの読み取りから始まります。この間。私が理解していないのは、これが行動にどのような影響を与えるかですwrite

マニュアルpipe(7)ページには次のように記載されています。

パイプの読み取り終了を参照するすべてのファイル記述子が閉じられた場合書く(2) 呼び出しプロセスに対して SIGPIPE 信号が生成されます。

この条件は私には明確に聞こえません。 ㅏ閉鎖ファイル記述子は、ファイル記述子ではなくなりました。そうですか?どうすればいいですか?」パイプの読み取り端が閉じた。「違う」パイプの読み取り端が開いていません。「?

私の質問が十分に明確になることを願っています。さて、、、open演算に関連するUnixパイプ機能について詳しく見てみるよう提案していただければ幸いです。closereadwrite

ベストアンサー1

お客様の例では a の代わりにfifoa を使用するため、pipe以下が適用されます。fifo(7)pipe(7)また、次のように言いました。

FIFO (先入れ先出しの省略形) はファイルシステム (mkfifo(3) を使用して作成されます) に名前を持ち、 open(2) を使用して開きます。ファイル権限が許可されている場合は、すべてのプロセスでFIFOを開くことができます。読み出し側を開くには O_RDONLY フラグを使用し、書き込み側を開くには O_WRONLY フラグを使用します。 詳細については、fifo(7) を参照してください。 注:FIFOにはファイルシステムにパス名がありますが、FIFOのI / Oには基本デバイス(存在する場合)の操作は含まれていません。

パイプとFIFOのI / O
パイプとFIFOの唯一の違いは、作成と開く方法です。これが完了すると、パイプとFIFOのI / Oはまったく同じ意味を持ちます。

それからこれからfifo(7):

カーネルは、1 つ以上のプロセスで開かれた各 FIFO 特殊ファイルのパイプオブジェクトを維持します。データを転送するには、まずFIFO(読み取りと書き込み)の両方を開く必要があります。通常、もう一方の端も開くまでFIFOブロックを開きます。

したがって、書き込みブロックは、両端(少なくとも1つのリーダーと1つのライターを意味します)が開く前に続きますfifo(7)。両端が開いて読み出しが閉じた後、書き込みは要求に応じてSIGPIPEを生成しますpipe(7)

パイプの使用(fifoではない)の例については、以下を参照してください。例セクションpipe(2): Pipe()(pipe() は実際にオープンパイプのペアを生成するため、open() なし)、close()、read()、write() および fork()(パイプを使用する場合、ほぼ常に fork() が含まれます。)))。

fifoへの書き込み中に死にたくない場合は、独自のCコードでSIGPIPEを処理する最も簡単な方法は、signal(SIGPIPE, SIG_IGN);各write()の後にerrnoをチェックして呼び出して処理することです。EPIPE

おすすめ記事