Differenza tra fflush e fsync
Domanda
Ho pensato fsync()
non fflush()
internamente, in modo da utilizzare fsync()
su un flusso è OK. Ma io sono sempre un risultato imprevisto quando viene eseguito sotto rete di I / O.
Il mio frammento di codice:
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);
Ma sembra _commit()
non è vampate di calore i dati (ho provato su Windows e i dati sono stati scritti su un Linux esportato file system).
Quando ho cambiato il codice per essere:
FILE* fp = fopen(file, "wb");
/* multiple fputs() calls like: */
fputs(buf, fp);
...
...
fputs(buf.c_str(), fp);
/* fflush the data */
fflush(fp);
fclose(fp);
svuota i dati.
Mi chiedo se _commit()
fa la stessa cosa come fflush()
. Eventuali ingressi?
Soluzione
fflush()
funziona su FILE*
, solo svuota i buffer interni nel FILE*
dell'applicazione fuori per il sistema operativo.
fsync
lavora su un livello più basso, racconta il sistema operativo per svuotare i buffer al supporto fisico.
sistemi operativi dati pesantemente della cache si scrive in un file. Se il sistema operativo applicata ogni scrittura per colpire il disco, le cose sarebbero molto lento. fsync
(tra le altre cose) consente di controllare quando i dati dovrebbero colpire l'unità.
Inoltre, fsync / commit opere su un descrittore di file. E non è a conoscenza di un FILE*
e non può lavare suoi buffer. FILE*
vive nella vostra applicazione, descrittori di file vivono nel kernel del sistema operativo, in genere.
Altri suggerimenti
La funzione C fflush()
standard e la chiamata di sistema fsync()
POSIX sono concettualmente in qualche modo simile. fflush()
opera su flussi di file C (oggetti FILE
), ed è quindi portatile.
fsync()
operare su descrittori di file POSIX.
Sia i dati causare buffer da inviare a una destinazione.
In un sistema POSIX, ogni file C flusso ha un descrittore di file associato , e tutte le operazioni su un flusso di file C saranno attuate delegando, quando necessario, per chiamate di sistema POSIX che operano sul descrittore di file.
Si potrebbe pensare che una chiamata a fflush
su un sistema POSIX causerebbe un write
di tutti i dati nel buffer del flusso di file, seguita da una chiamata di fsync()
per il file descrittore di quel flusso di file. Quindi, su un sistema POSIX non ci sarebbe alcun bisogno di seguire una chiamata a fflush
con una chiamata a fsync(fileno(fp))
. Ma è che il caso: c'è una chiamata a fsync
da fflush
No, si chiamerà chiamando fflush
su un sistema POSIX non implica che fsync
.
Lo standard C per fflush
dice (enfasi aggiunta) è
fa sì che i dati non scritti per [la] flusso da consegnare per l'ambiente host da scrivere per il file
Dire che i dati sono essere scritto, piuttosto che quello è è scritto implica che un ulteriore buffer per l'ambiente host è permesso. Questo buffer dalla "ambiente host" potrebbe includere, per un ambiente POSIX, il buffer interno che fsync
vampate. Quindi, una lettura attenta dello standard C suggerisce che la norma non richiede l'implementazione di chiamare POSIX fsync
.
Il POSIX descrizione standard di fflush
non dichiara, come estensione del C semantica , che è chiamato fsync
.
Potrei dire che per semplicità:
utilizzo fsync()
con non lo streaming di file (file descriptor intero)
utilizzo fflush()
con flussi di file.
Anche qui è l'aiuto da uomo:
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()
e fsync()
possono essere utilizzati per cercare di garantire che i dati vengono scritti sul supporto di archiviazione (ma non è essere sempre possibile):
- primo utilizzo
fflush(fp)
sul flusso di uscita (fp
essendo unFILE *
ottenuto dafopen
o uno dei flussistdout
standard ostderr
) per scrivere il contenuto del buffer associato al flusso all'OS. - quindi utilizzare
fsync(fileno(fp))
per dire al sistema operativo di scrivere i propri buffer per il supporto di memorizzazione.
Si noti tuttavia che fileno()
e fsync()
sono funzioni POSIX che potrebbero non essere disponibili su tutti i sistemi, in particolare i sistemi legacy di Microsoft in cui le alternative possono essere nominati _fileno()
, _fsync()
o _commit()
...
Per forzare l'impegno delle recenti modifiche al disco, utilizzare la sincronizzazione () o fsync funzioni ().
fsync () sarà sincronizzare tutti i dati e metadati del file dato con il dispositivo di memorizzazione permanente. Dovrebbe essere chiamato poco prima che il file corrispondente è stato chiuso.
sync () si impegneranno tutti i file modificati su disco.
Credo che al di sotto di documento da python ( https://docs.python.org/ 2 / library / os.html ) chiarisce molto bene.
os.fsync (fd) Forza la scrittura di file con descrittore fd disco. Sopra Unix, questo chiama la funzione nativa fsync (); su Windows, MS _commit () la funzione.
Se stai iniziando con un oggetto file di Python f, in primo luogo fare f.flush (), e poi os.fsync (f.fileno ()), per garantire che tutti i cuscinetti interni associata ad f vengono scritti sul disco.
Disponibilità: Unix, e Windows a partire dal 2.2.3
.