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?

È stato utile?

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

  1. primo utilizzo fflush(fp) sul flusso di uscita (fp essendo un FILE * ottenuto da fopen o uno dei flussi stdout standard o stderr) per scrivere il contenuto del buffer associato al flusso all'OS.
  2. 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

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top