マニュアルページによると、 "write count bytes"コマンドを作成し、書き込まれた実際のバイト数を返します。したがって、すべてのバイトがファイル記述子に書き込まれていることを確認するには、書き込みをループに入れ、すべてのバイトが書き込まれていることを監視する必要があります。
しかし、ブロックが書き込まれるまで書き込むようにファイル記述子を設定する方法はありますか?みんなバイトが書き込まれましたか?
編集*違いがあればパイプラインに書き込んでいます。
答え1
あなたはシステムコールだけに言及したので、システムコールインターフェイスを介してすべてのデータをOSに転送したいとします。
したがって、すべてのバイトがファイル記述子に書き込まれていることを確認するには、書き込みをループに入れ、すべてのバイトが書き込まれていることを監視する必要があります。
はい。
私が(Linuxで)テストした限り、ほとんどの書き込みは実際にすべてが書き込まれるまでブロックされます。これには、少なくとも通常のファイルと(私が覚えている限り)パイプに書き込むことが含まれます。もちろん、ファイルディスクリプタを非ブロックモードに設定すると、これは起こらない可能性があります(通常のファイルで動作しているかどうかはわかりません)、システムコールの途中でシグナルを受け取ることができます。ここでの正確な動作はシステムによって異なる場合があります。
しかし、すべてのバイトが書き込まれるまでブロックが書き込まれるようにファイル記述子を設定する方法はありますか?
いいえ。
システムコールがシグナルによって中断され、制御がプログラムに戻されると、続行したくない場合があります。したがって、続行するかどうかを決定するのはアプリケーションによって異なります。
答え2
2つのオプションがあります。
O_SYNCフラグでopenを使用してください。マンページから:
O_SYNC Write operations on the file will complete according to the re‐
quirements of synchronized I/O file integrity completion (by
contrast with the synchronized I/O data integrity completion
provided by O_DSYNC.)
By the time write(2) (or similar) returns, the output data and
associated file metadata have been transferred to the underlying
hardware (i.e., as though each write(2) was followed by a call
to fsync(2)). See NOTES below.
あるいは、書き込み呼び出しの後にfsync(2)呼び出しを使用すると、データは明示的にフラッシュされます。
パフォーマンスと保証の要件に応じて、どちらかを優先できます。
あなたの質問はパイプに関するものなので、必要ありません。すべての書き込みはパイプに移動し、エラーが発生しない限り(非ブロックモードでパイプがいっぱいになるなど)、同期/直接、またはフラグや特別な呼び出しが必要ない限り作成されたと見なされます。パイプリーダーがデータを読み取るまで書き込みから戻りを遅らせることについて話している場合は、要件を再確認する必要があります。読者がアクセスするまで、書き込みが常にブロックされるように制限されたバッファを持つパイプを作成することは可能ですが、なぜそのようなシナリオを設計してテストするのが難しいのでしょうか。読者からのフィードバックが本当に必要な場合は、明示的に要求する必要があります。パイプから読み取りを呼び出した後、リーダーがすぐに死ぬ可能性は常にあるため、パイプをブロックしてシナリオを作成することは役に立たないようです。