私は設定ファイルと対話するライブラリを持っています。ライブラリがインポートされると、初期化コードは設定ファイルを読み込み、おそらくそれを更新し、更新された内容をファイルに書き戻します(何も変更されていなくても)。Pythonはいつファイルをディスクに書き出しますか?
非常に時折、設定ファイルの内容が消えるという問題が発生します。具体的には、これは短いスクリプト(ライブラリを使用して)を何度も繰り返し実行したときに発生します。同じディレクトリの中で決して起こることはありません。それは、それが若干ランダムな問題、具体的にはI/Oの競合状態であると信じさせています。
これは問題を確実に再現することはできず、一部のシステムでのみ発生するため、これはデバッグするのに苦労します。私は何が起こるのか疑問を呈していますが、私はPythonでファイルI/Oの画像が正しいかどうかを見たいと思っていました。
質問:Pythonプログラムは実際にファイルの内容をディスクに書き込むのはいつですか?ファイルが閉じた時点で内容がディスクになると思っていましたが、このエラーを説明できません。 Pythonがファイルを閉じるときに、内容をディスク自体にフラッシュするのか、それとも単にファイルシステムにキューイングするのでしょうか? Pythonの終了後にファイルの内容をディスクに書き込むことは可能でしょうか?そして、fp.flush(); os.fsync(fp.fileno())
(fp
はファイルハンドルです)を使用してこの問題を回避できますか?
私はUnixシステム(特にMac OS X)でプログラミングしています。 編集:また、プロセスが同時に実行されていないことに注意してください。
付録:ここでは、私は疑う特定の競合状態です:
- プロセス#1が起動されます。
- プロセス#1は、コンフィギュレーションファイルを読み取りモードで開き、終了すると閉じます。
- プロセス#1は、コンフィギュレーションファイルを書き込みモードで開き、すべての内容を消去します。内容の消去は、ディスクに同期されます。
- プロセス#1は新しい内容をファイルハンドルに書き込み、それを閉じます。
- プロセス#1:ファイルを閉じると、PythonはOSに、これらの内容をディスクに書き込むようにキューに入れるように指示します。
- プロセス#1が閉じて、
- プロセス#2を出て呼び出さ
- プロセス#2で読み取りモードで設定ファイルを開きますが、新しい内容はまだ同期されません。プロセス#2は空のファイルを見る。
- プロセス2がファイルを読み取った後、OSは最終的にディスクに内容の書き込みを終了します。
- プロセス2は、ファイルが空であると考えて、構成ファイルのデフォルトを設定します。
- プロセス#2は、コンフィギュレーションファイルのバージョンをディスクに書き込み、最後のバージョンを上書きします。
いいえ、Pythonがファイルを閉じると、ファイルはディスクにフラッシュされていません。私はあなたが思うよりも早くプロセス#2がファイルを開くと言うでしょう。 –
複数のプロセスが同時にファイルにアクセスし、少なくとも1つがそのプロセスに書き込む場合は、プロセスを同期させて一貫した結果を得る必要があります。これはPython固有のものではありません。 –
OSがデータをディスクに書き込まなくても、そのファイルにアクセスする誰かが共有するメモリキャッシュがあるため、Pythonからフラッシュされている限り、ファイルの内容を2.プロセスに返すことが保証されます。 (一貫性のために構成されていない共有ファイルシステム上の別のマシン上でプロセスを実行している場合や、ファイルを上書きする競合状態が発生している場合を除く) – nos