名前付きパイプへの同時書き込みの保証は何ですか?


32

たとえば、次のような名前付きパイプを作成しました。

mknod myPipe p

そして、いくつかのプロセス(たとえば、いくつかのサーバー)から読み取ります。例として、tailを使用しました。

tail -f myPipe

複数のクライアントプロセスがメッセージを書き込む場合(たとえば、次のようにecho "msg" >> myPipe、メッセージがインターリーブされる可能性があります:

 <beginning of message1><message2><ending of message1>

または、名前付きパイプへの書き込みプロセスはアトミックですか?

回答:


29

それは、各プロセスがどれだけ書いているかに依存します(この点でOSがPOSIXに準拠していると仮定します)。からwrite()

パイプまたはFIFOへの書き込み要求は、次の例外を除き、通常のファイルと同じ方法で処理されます。
[...]

  • {PIPE_BUF}バイト以下の書き込み要求は、同じパイプで書き込みを行う他のプロセスからのデータとインターリーブさません。{PIPE_BUF}バイトを超える書き込みでは、ファイルステータスフラグのO_NONBLOCKフラグが設定されているかどうかに関係なく、任意の境界で他のプロセスによる書き込みとデータがインターリーブされる場合があります。

また、内根拠セクションパイプとFIFOについて:

  • アトミック/非アトミック:1つの操作で書き込まれた全量が他のプロセスからのデータでインターリーブされない場合、書き込みはアトミックです。これは、単一のリーダーにデータを送信する複数のライターがある場合に便利です。アプリケーションは、書き込み要求がアトミックに実行されると予想される大きさを知る必要があります。この最大値は{PIPE_BUF}と呼ばれます。POSIX.1-2008のこのボリュームは、{PIPE_BUF}バイトを超える書き込み要求がアトミックかどうかを示していませんが、{PIPE_BUF}バイト以下の書き込みはアトミックである必要があります。

値if PIPE_BUFは各実装で定義されますが、最小値は512バイトです(を参照limits.h)。Linuxでは、4096バイトです(を参照pipe(7))。


5
ちなみに、PIPE_BUFは少なくとも512であることが保証されています。また、単一の書き込み呼び出しでプロセスが実際に各行を書き込むことも保証する必要があることに注意してください。行バッファリング(setvbuf(stdout, NULL, _IOLBF,512))を有効にすると、低レベルの関数を使用する必要なしにこれが実行されます。
Random832

PIPE_BUF一般的なUnixシステムで観測された値の表を次に示します。ar.to
Arto Bendiken 14年

ソケットをどのように多重化できるかわかりませんが、名前付きパイプはできませんか?UNIX上のすべてはただのファイルですよね?lulz
アレクサンダー・ミルズ

@AlexanderMills:あなたのコメントがわかりません
マット

1
@AlexanderMills:いいえ、それは最小値です
マット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.