web-dev-qa-db-ja.com

pythonのfile.flush()は正確に何をしているのですか?

これはPython ファイルオブジェクトのドキュメント で見つけました。

flush()は、必ずしもファイルのデータをディスクに書き込むとは限りません。この動作を保証するには、flush()に続いてos.fsync()を使用します。

だから私の質問は次のとおりです。Pythonのflushは何をしているのでしょうか。ディスクにデータを書き込むことを強制すると考えていましたが、今はそうではないことがわかります。どうして?

122
geek

通常、2つのレベルのバッファリングが関係します。

  1. 内部バッファー
  2. オペレーティングシステムのバッファ

内部バッファーは、プログラミング対象のランタイム/ライブラリ/言語によって作成されたバッファーであり、書き込みごとにシステムコールを回避することで速度を上げることを目的としています。代わりに、ファイルオブジェクトに書き込むときは、そのバッファーに書き込みます。バッファーがいっぱいになると、システムコールを使用してデータが実際のファイルに書き込まれます。

ただし、オペレーティングシステムのバッファが原因で、データが書き込まれることを意味しない場合がありますディスクに。ランタイムによって維持されているバッファからオペレーティングシステムによって維持されているバッファにデータがコピーされることを意味する場合があります。

何かを書いて、それがバッファ(のみ)になり、マシンの電源が切れた場合、マシンの電源が切れてもそのデータはディスク上にありません。

そのため、それを支援するために、それぞれのオブジェクトにflushメソッドとfsyncメソッドがあります。

最初のflushは、プログラムバッファに残っているデータを実際のファイルに単に書き出すだけです。通常、これは、データがプログラムバッファからオペレーティングシステムバッファにコピーされることを意味します。

具体的には、別のプロセスが同じファイルを読み取り用に開いている場合、ファイルにフラッシュしたばかりのデータにアクセスできることを意味します。ただし、必ずしも「永続的に」ディスクに保存されたことを意味するわけではありません。

そのためには、os.fsyncメソッドを呼び出す必要があります。これにより、すべてのオペレーティングシステムバッファーが対象のストレージデバイスと同期されます。つまり、そのメソッドはデータをオペレーティングシステムバッファーからディスクにコピーします。

通常、どちらの方法でも気にする必要はありませんが、実際にディスク上で何が起こるかについての妄想が良いシナリオである場合、指示に従って両方の呼び出しを行う必要があります。


2018年の補遺。

キャッシュメカニズムを備えたディスクは2013年に比べてはるかに一般的になっているため、キャッシュとバッファーのレベルがさらに増えていることに注意してください。 I assumeこれらのバッファは、sync/flush呼び出しによっても処理されますが、実際にはわかりません。

オペレーティングシステムがそうしないかもしれないからです。フラッシュ操作は、ファイルデータをRAMのファイルキャッシュに強制的に入れ、そこから実際にディスクに送信するのはOSの仕事です。

内部バッファーをフラッシュします。これにより、OSがバッファーをファイルに書き出すことになります。[1] Pythonは、特に設定しない限り、OSのデフォルトのバッファリングを使用します。

しかし、OSが依然として協力しないことを選択する場合があります。特に、Windows/NTFSでの書き込み遅延のようなすばらしいものを使用します。基本的に、内部バッファはフラッシュされますが、OSバッファはまだ保持しています。そのため、これらの場合、os.fsync()を使用してディスクに書き込むようにOSに指示する必要があります。

[1] http://docs.python.org/library/stdtypes.html

6
Dan

基本的に、flush()はRAMバッファーを消去します。その本当の力は、後で書き込みを続けることができるということです。 RAMをフラッシュして、さらに多くのデータを取得します。それだけです。データがファイルに安全に書き込まれるようにするには、代わりにclose()を使用します。

0
zA.