Diferencia entre fflush y fsync


Pensé que fsync() hace fflush() internamente, por lo que usar fsync() en una secuencia está bien. Pero estoy obteniendo un resultado inesperado cuando se ejecuta bajo E/S de red.

Mi fragmento de código:

FILE* fp = fopen(file,"wb");
/* multiple fputs() call 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);

Pero parece que _commit() no está limpiando los datos (lo intenté en Windows y los datos se escribieron en el sistema de archivos exportado de Linux).

Cuando cambié el código como:

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

Esta vez vacía los datos.

Me pregunto si _commit() hace lo mismo que fflush(). Cualquier las entradas?

Author: Drakonoved, 2010-02-26

5 answers

fflush() funciona en FILE*, simplemente limpia los búferes internos en el FILE* de su aplicación hacia el sistema operativo.

fsync funciona en un nivel inferior, le dice al sistema operativo que vacíe sus búferes a los medios físicos.

OSs almacena en caché los datos que escribe en un archivo. Si el sistema operativo forzara cada escritura para golpear la unidad, las cosas serían muy lentas. fsync (entre otras cosas) le permite controlar cuándo los datos deben golpear la unidad.

Además, fsync / commit funciona en un archivo descriptor. No tiene conocimiento de un FILE* y no puede limpiar sus búferes. FILE* vive en su aplicación, los descriptores de archivo viven en el núcleo del sistema operativo, normalmente.

 70
Author: nos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-02 07:16:49

La función C estándar fflush() y la llamada al sistema POSIX fsync() son conceptualmente algo similares. fflush() opera en flujos de archivos C (objetosFILE), y por lo tanto es portable. fsync() funciona con descriptores de fichero POSIX. Ambos hacen que los datos almacenados en búfer se envíen a un destino.

En un sistema POSIX, cada flujo de archivos C tiene un descriptor de archivo asociado , y todas las operaciones en un flujo de archivos C se implementarán delegando, cuando sea necesario, a las llamadas al sistema POSIX que operar sobre el descriptor de fichero.

Uno podría pensar que una llamada a fflush en un sistema POSIX causaría un write de cualquier dato en el búfer del flujo de archivos, seguido de una llamada de fsync() para el descriptor de archivo de ese flujo de archivos. Así que en un sistema POSIX no habría necesidad de seguir una llamada a fflush con una llamada a fsync(fileno(fp)). Pero es ese el caso: ¿hay una llamada a fsync desde fflush?

No, llamar a fflush en un sistema POSIX no implica que fsync será called.

El estándar C para fflush dice (énfasis añadido) que

Hace que cualquier dato no escrito para [el] flujo que se entregue al entorno host se escriba en el archivo

Decir que los datos son para serescrito, en lugar de que es es escrito implica que más buffering por el entorno host está permitido. Que el almacenamiento en búfer por el "entorno host" podría incluir, para un entorno POSIX, el buffering que fsync se vacía. Así que una lectura cercana del estándar C sugiere que el estándar no requiere que la implementación POSIX llame a fsync.

El POSIX descripción estándar de fflush no declara, como una extensión de la semántica C, que fsync se llama.

 5
Author: Raedwald,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-12 14:10:38

Podría decir que por simplicidad:

Use fsync() con archivos no streaming (descriptores de archivos enteros)

Use fflush() con secuencias de archivos.

También aquí está la ayuda del hombre:

int fflush(FILE *stream); // flush a stream, FILE* type

int fsync(int fd); // synchronize a file's in-core state with storage device
                    // int type
 2
Author: pulse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-04 15:29:06

Para forzar el compromiso de cambios recientes en el disco, use las funciones sync() o fsync ().

fsync() sincronizará todos los datos y metadatos del archivo dado con el dispositivo de almacenamiento permanente. Debe ser llamado justo antes de que el archivo correspondiente haya sido cerrado.

sincronizar() enviará todos los archivos modificados al disco.

 0
Author: user3428045,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-05 14:24:45

Creo que debajo del documento de python ( https://docs.python.org/2/library/os.html ) lo aclara muy bien.

Os.fsync (fd) Fuerza la escritura del archivo con filedescriptor fd al disco. En Unix, esto llama a la función nativa fsync (); en Windows, el MS _commit() función.

Si está comenzando con un objeto de archivo Python f, primero haga f. flush(), y luego hacer os.fsync (f. fileno ()), para asegurar que todos los búferes internos asociados con f se escriben en el disco.

Disponibilidad: Unix y Windows a partir de la versión 2.2.3.

 0
Author: poordeveloper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-23 02:20:56