Diferencia entre fflush y fsync
Pregunta
pensé fsync()
hace fflush()
internamente, por lo que usar fsync()
en una corriente está bien. Pero estoy recibiendo un resultado inesperado cuando se ejecuta bajo la red de E / S.
Mi fragmento de código:
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);
Pero parece _commit()
no está vaciando los datos (probé en Windows y se escribieron los datos en un sistema de archivos de Linux exportado).
Cuando cambié el código a ser:
FILE* fp = fopen(file, "wb");
/* multiple fputs() calls like: */
fputs(buf, fp);
...
...
fputs(buf.c_str(), fp);
/* fflush the data */
fflush(fp);
fclose(fp);
vuelca los datos.
Me pregunto si _commit()
hace lo mismo que fflush()
. Cualquier entrada?
Solución
fflush()
trabaja en FILE*
, sólo vacía los buffers internos en el FILE*
de su aplicación a cabo con el sistema operativo.
Producción fsync
en un nivel más bajo, le dice al sistema operativo para vaciar sus buffers a los medios físicos.
sistemas operativos en gran medida en caché los datos se escriben en un archivo. Si el sistema operativo hace cumplir cada escritura para golpear la unidad, las cosas serían muy lento. fsync
(entre otras cosas) le permite controlar cuando los datos deben golpear la unidad.
Además, fsync / commit obras en un descriptor de archivo. Se tiene conocimiento de un FILE*
y no puede vaciar sus buffers. FILE*
vidas en su aplicación, los descriptores de fichero viven en el núcleo del sistema operativo, por lo general.
Otros consejos
El fflush()
función C estándar y la llamada al sistema fsync()
POSIX son conceptualmente algo similar. fflush()
opera sobre flujos de archivos C (objetos FILE
), y por tanto es portátil.
fsync()
operar en los descriptores de archivos POSIX.
Tanto los datos de causa tamponada a ser enviados a un destino.
En un sistema POSIX, cada archivo de flujo C tiene un archivo asociado descriptor , y todas las operaciones en una secuencia de archivo C se llevarán a cabo mediante la delegación, cuando sea necesario, a las llamadas del sistema POSIX que operan en el descriptor de archivo.
Uno podría pensar que una llamada a fflush
en un sistema POSIX causaría una write
de los datos en el búfer de la secuencia de archivo, seguido de una llamada de fsync()
para el descriptor de archivo de esa secuencia de archivo. Así que en un sistema POSIX no habría ninguna necesidad de seguir una llamada a fflush
con una llamada a fsync(fileno(fp))
. Pero es que el caso: ¿hay una llamada a fsync
de fflush
No, llamando fflush
en un sistema POSIX no implica que fsync
se llamará.
El estándar C para fflush
dice (énfasis añadido) que
hace que los datos no guardados de [la] corriente para ser entregado al entorno host a escribirse en el fichero
Al decir que los datos son sea por escrito, en lugar de esto es es escrito implica que se permite más de amortiguación por el entorno de acogida. Eso amortiguando por el "entorno de acogida" podría incluir, por un entorno POSIX, el búfer interno que rubores fsync
. Por lo que una lectura atenta de la norma C sugiere que la norma no requiere la aplicación POSIX a fsync
llamada.
El POSIX descripción estándar de fflush
no declara, como una extensión de la semántica C , que fsync
se llama.
Yo podría decir que por simplicidad:
El uso fsync()
con no transmisión de archivos (descriptores de fichero)
El uso fflush()
con secuencias de archivo.
También en este caso es 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
fflush()
y fsync()
se pueden utilizar para tratar de asegurar que los datos se escriben en los medios de almacenamiento (pero no siempre es ser posible):
- primer uso
fflush(fp)
en el flujo de salida (fp
ser unFILE *
obtenida defopen
o uno de los flujos estándaresstdout
ostderr
) para escribir el contenido de la memoria intermedia asociada con el flujo al sistema operativo. - a continuación, utilizar
fsync(fileno(fp))
para decirle al sistema operativo para escribir sus propias memorias intermedias a los medios de almacenamiento.
Nota sin embargo, que fileno()
y fsync()
son funciones POSIX que podrían no estar disponibles en todos los sistemas, en particular los sistemas heredados de Microsoft donde las alternativas pueden ser designados _fileno()
, _fsync()
o _commit()
...
Para forzar el compromiso de los recientes cambios en el disco, utilice el () funciones de sincronización () o fsync.
fsync () sincronizar todos los datos y metadatos del archivo dado con el dispositivo de almacenamiento permanente. Debería llamarse justo antes del archivo correspondiente se ha cerrado.
sync () se comprometan todos los archivos modificados en el disco.
creo que a continuación el documento de pitón ( https://docs.python.org/ 2 / biblioteca / os.html ) aclara muy bien.
os.fsync (fd) Fuerza de escritura de archivo con un descriptor de archivo fd en el disco. En Unix, esto llama a la función nativa fsync (); En Windows, el MS _commit () función.
Si vas a empezar con un archivo de objetos Python f, hacer primero f.flush (), y luego hacer os.fsync (f.fileno ()), para asegurar que todos los tampones internos asociada a f se escriben en el disco.
Disponibilidad:. Unix y Windows a partir de 2.2.3