web-dev-qa-db-ja.com

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

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

mknod myPipe p

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

tail -f myPipe

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

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

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

32
Rogach

これは、各プロセスが書き込んでいる量に依存します(この点に関して、OSがPOSIXに準拠していると想定)。 write() から:

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

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

また、パイプとFIFOに関する Rationaleセクション

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

_PIPE_BUF_が各実装で定義されている場合の値ですが、最小値は512バイトです( _limits.h_ を参照)。 Linuxでは、4096バイトです( pipe(7) を参照)。

29
Mat