2つのファイル記述子を同じファイル(読み取り用と書き込み用)に同期する方法

2つのファイル記述子を同じファイル(読み取り用と書き込み用)に同期する方法

次のコードがあります。

FILE *file = fopen("testfile.txt", "r+");
int fdfile = open("testfile.txt", O_RDONLY | O_SYNC);

const char word[] = "writing to a file and read test";
fwrite(word, sizeof(word)-1, 1, file);

fsync(fdfile);

char word1[1024] = {0};
int n = read(fdfile, word1, sizeof(word)-1);

printf("%s\n%d", word1, n);

fclose(file);

実行直前にファイルにtestfile.txt内容が含まれています。prev content

これを実行すれば私は得る。

prev content
12

最新のコンテンツでなければなりませんがwriting to a file and read test。私はそれをfsync(fdfile)無駄に使用しました。私も試しましたが、sync()そのうちfsync(fileno(file))何も動作しませんでした。書き込み後にコンテンツをディスクにフラッシュする必要があるため、機能する必要がありますが機能しませんでした。

読み取りと書き込みに同じファイル記述子を使用すると、この問題を軽減できることがわかりますが、私のコードではこれを行うことはできません。この問題を軽減してコンテンツを同期するにはどうすればよいですか?

ベストアンサー1

open()read()およびその他の関数は、write()Posixで定義された低レベル関数です。これには通常、物理メディアにフラッシュするために使用されるバッファーであるシステムレベル(カーネル)バッファーが含まれ、fsync()これには多くの制御がありません。

fopen()、、fread()その他の機能は、fwrite()C言語で提供される高度な機能です。彼らは含まれています追加を使用してバッファを設定できますsetbuf()。このバッファは通常テキストファイル(、\nおよびを含む)のラインバッファ(ラインの各端でフラッシュされます)、バイナリファイルのブロックバッファ(バッファがいっぱいになるとフラッシュされます)です。stdinstdoutstderr

もちろん、低レベルと高レベルの読み取り/書き込み機能への呼び出しを混在させることはお勧めできません。問題は、使用中の高レベルバッファがフラッシュされていないために発生しますfwrite()(フラッシュに使用した低レベルバッファにフラッシュfsync())。

解決策は呼び出すfsync()か開かないことですO_SYNC(コードから削除できます)。

  • fflush()必要に応じて拡張バッファを明示的にフラッシュします。
  • または、高度な機能をバッファリングされていない状態にします。setbuf(fdfile, _IONBF)

後者の方が簡単ですが、バッファーは効率性のためであり、バッファリングをオフにすると、上位レベルの呼び出しが各呼び出しでそのfwrite()システムwrite()呼び出しをトリガーしてパフォーマンスに影響を与える可能性があるため、fflush()必要に応じて注意を払う必要があります。これをやっています。

おすすめ記事