¿Qué está haciendo exactamente el archivo.flush () del python?

Encontré esto en la documentación de Python para objetos de archivo :

flush () no necesariamente escribe los datos del archivo en el disco. Use flush () seguido de os.fsync () para asegurar este comportamiento.

Así que mi pregunta es: ¿qué está haciendo exactamente la flush de Python? Pensé que obliga a escribir datos en el disco, pero ahora veo que no lo hace. ¿Por qué?

Normalmente hay dos niveles de almacenamiento en búfer implicados:

  1. Tampones internos
  2. Buffer del sistema operativo

Los búferes internos son búferes creados por el tiempo de ejecución / biblioteca / lenguaje con el que está progtwigndo y está destinado a acelerar las cosas al evitar llamadas al sistema para cada escritura. En cambio, cuando escribe en un objeto de archivo, escribe en su búfer, y cada vez que el búfer se llena, los datos se escriben en el archivo real mediante llamadas al sistema.

Sin embargo, debido a los búferes del sistema operativo, esto podría no significar que los datos se escriben en el disco . Solo puede significar que los datos se copian de los buffers mantenidos por su tiempo de ejecución en los buffers mantenidos por el sistema operativo.

Si escribe algo, y termina en el búfer (solo), y la alimentación se corta en su máquina, esos datos no están en el disco cuando la máquina se apaga.

Entonces, para ayudar con eso, tiene los métodos flush y fsync , en sus respectivos objetos.

El primero, al flush , simplemente escribirá cualquier dato que perdure en un búfer de progtwig en el archivo real. Normalmente, esto significa que los datos se copiarán desde el búfer del progtwig al búfer del sistema operativo.

Específicamente, lo que esto significa es que si otro proceso tiene ese mismo archivo abierto para leer, podrá acceder a los datos que acaba de vaciar en el archivo. Sin embargo, no significa necesariamente que haya sido almacenado “permanentemente” en el disco.

Para hacerlo, debe llamar al método os.fsync , que garantiza que todos los búferes del sistema operativo estén sincronizados con los dispositivos de almacenamiento para los que están, en otras palabras, ese método copiará los datos de los búferes del sistema operativo al disco.

Por lo general, no es necesario que se moleste con ninguno de los dos métodos, pero si se encuentra en una situación en la que la paranoia sobre lo que realmente termina en el disco es algo positivo, debe hacer ambas llamadas según las instrucciones.


Adenda en 2018.

Tenga en cuenta que los discos con mecanismos de caché ahora son mucho más comunes que en 2013, por lo que ahora hay incluso más niveles de almacenamiento en caché y buffers involucrados. Supongo que estos buffers también serán manejados por las llamadas de sincronización / descarga, pero realmente no lo sé.

Porque el sistema operativo no puede hacerlo. La operación de descarga obliga a los datos del archivo a la memoria caché de archivos en la RAM, y desde allí es tarea del sistema operativo enviarlos al disco.

Se vacía el búfer interno, que se supone que causa que el sistema operativo escriba el búfer en el archivo. [1] Python utiliza el búfer predeterminado del SO a menos que lo configure, de lo contrario.

Pero a veces el sistema operativo sigue optando por no cooperar. Especialmente con cosas maravillosas como retrasos de escritura en Windows / NTFS. Básicamente, el búfer interno se vacía, pero el búfer del sistema operativo aún lo mantiene. Por lo tanto, debe indicar al sistema operativo que lo escriba en el disco con os.fsync() en esos casos.

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

Básicamente, flush () limpia su búfer de RAM, su verdadero poder es que le permite seguir escribiendo en él después, pero no debe considerarse como la mejor / más segura función de escritura en archivo. Está vaciando su RAM para que lleguen más datos, eso es todo. Si desea asegurarse de que los datos se escriban en un archivo de forma segura, utilice en su lugar close ().