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?

¿Fue útil?

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):

  1. primer uso fflush(fp) en el flujo de salida (fp ser un FILE * obtenida de fopen o uno de los flujos estándares stdout o stderr) para escribir el contenido de la memoria intermedia asociada con el flujo al sistema operativo.
  2. 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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top