66

fsync()私はfflush()内部的にそう思ったのでfsync()、ストリームで使用しても問題ありません。しかし、ネットワーク I/O で実行すると予期しない結果が得られます。

私のコードスニペット:

FILE* fp = fopen(file, "wb");
/* multiple fputs() calls like: */
fputs(buf, fp);
...
...
fputs(buf.c_str(), fp);
/* get fd of the FILE pointer */
fd = fileno(fp);
#ifndef WIN32
ret = fsync(fd);
#else
ret = _commit(fd);
fclose(fp);

しかし_commit()、データをフラッシュしていないようです (私は Windows で試しましたが、データは Linux のエクスポートされたファイルシステムに書き込まれました)。

コードを次のように変更したとき:

FILE* fp = fopen(file, "wb");
/* multiple fputs() calls like: */
fputs(buf, fp);   
...   
...
fputs(buf.c_str(), fp);
/* fflush the data */
fflush(fp);
fclose(fp);

データをフラッシュします。

_commit()と同じことをするかどうか疑問に思っていfflush()ます。入力はありますか?

4

6 に答える 6

101

fflush()で動作し、アプリケーションFILE*の内部バッファを OS にフラッシュするだけです。FILE*

fsync下位レベルで動作し、OS にバッファを物理メディアにフラッシュするように指示します。

OS は、ファイルに書き込むデータを大量にキャッシュします。OS がすべての書き込みを強制的にドライブにヒットさせると、処理が非常に遅くなります。fsync(特に)データがドライブにヒットするタイミングを制御できます。

さらに、fsync/commit はファイル記述子に対して機能します。の知識がFILE*なく、そのバッファをフラッシュできません。FILE*アプリケーションに存在し、ファイル記述子は通常、OS カーネルに存在します。

于 2010-02-26T09:41:00.540 に答える
9

標準 C 関数fflush()と POSIX システム コールfsync() は概念的に似ています。fflush()C ファイル ストリーム (FILEオブジェクト) で動作するため、移植性があります。 fsync()POSIX ファイル記述子を操作します。どちらも、バッファリングされたデータが宛先に送信されます。

POSIX システムでは、各 C ファイル ストリームには関連付けられたファイル記述子があり、C ファイル ストリームに対するすべての操作は、必要に応じて、ファイル記述子を操作する POSIX システム コールに委譲することによって実装されます。

fflushPOSIX システムで を呼び出すwriteと、ファイル ストリームのバッファ内のすべてのデータが呼び出され、その後fsync()にそのファイル ストリームのファイル記述子が呼び出されると考える人もいるかもしれません。fflushしたがって、POSIX システムでは、 への呼び出しの後に への呼び出しを続ける必要はありませんfsync(fileno(fp))。しかし、そうですか: fsyncfromへの呼び出しはありfflushますか?

いいえ、fflushPOSIX システムで呼び出すことは、それfsyncが呼び出されることを意味するものではありません。

C標準はfflush言う(強調が追加された)それ

[the] ストリームの未書き込みデータがホスト環境に配信され、ファイルに書き込まれます。

データが書き込まれるのではなく、書き込まれるということは、ホスト環境による追加のバッファリングが許可されていることを意味します。「ホスト環境」によるそのバッファリングには、POSIX 環境の場合、フラッシュする内部バッファリングが含まれる場合があります。そのため、C 標準をよく読むと、標準では POSIX 実装で を呼び出す必要がないことがわかります。fsyncfsync

POSIX 標準記述ではfflush、C セマンティクスの拡張として、fsyncが呼び出されることを宣言していません。

于 2017-01-12T14:03:39.467 に答える
3

fflush()また、fsync()データがストレージ メディアに書き込まれることを確認するために使用できます (ただし、常に可能であるとは限りません)。

  1. 最初fflush(fp)に、出力ストリーム (または標準ストリームまたはのいずれかから取得)fpで使用して、ストリームに関連付けられたバッファーの内容を OS に書き込みます。FILE *fopenstdoutstderr
  2. 次にfsync(fileno(fp))、OS に独自のバッファをストレージ メディアに書き込むように指示するために使用します。

ただし、fileno()およびは、すべてのシステムで使用できるとは限らないfsync()POSIX 関数であること_fileno()に注意してください。_fsync()_commit()

于 2019-06-27T18:59:25.323 に答える
1

以下のpythonのドキュメント( https://docs.python.org/2/library/os.html)はそれを非常に明確にしていると思います。

os.fsync(fd) ファイル記述子 fd を持つファイルを強制的にディスクに書き込みます。Unix では、これはネイティブの fsync() 関数を呼び出します。Windows では、MS _commit() 関数。

Python ファイル オブジェクト f から開始する場合は、最初に f.flush() を実行し、次に os.fsync(f.fileno()) を実行して、f に関連付けられたすべての内部バッファーがディスクに書き込まれるようにします。

可用性: Unix、および 2.2.3 以降の Windows。

于 2017-11-23T02:20:56.760 に答える