Question

Je pensais que fsync() ne fflush() en interne, donc l'utilisation fsync() sur un cours d'eau est OK. Mais je reçois un résultat inattendu lorsqu'il est exécuté sous E / S réseau.

Mon extrait de code:

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

Mais il semble _commit() n'est pas le rinçage des données (j'ai essayé sur Windows et les données ont été écrites sur un système de fichiers exporté Linux).

Quand j'ai changé le code à:

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

il évacue les données.

Je me demande si _commit() fait la même chose que fflush(). Toutes les entrées?

Était-ce utile?

La solution

fflush() fonctionne sur FILE*, il débusque que les tampons internes dans le FILE* de votre application vers le système d'exploitation.

fsync fonctionne à un niveau inférieur, il indique le système d'exploitation pour vider ses tampons au support physique.

données fortement cache OSs vous écrire dans un fichier. Si le système d'exploitation appliqué chaque écriture pour frapper le lecteur, les choses seraient très lent. fsync (entre autres) vous permet de contrôler quand les données doivent frapper le lecteur.

En outre, fsync / commit travaux sur un descripteur de fichier. Il n'a pas connaissance d'un FILE* et ne peut pas vider ses tampons. vit FILE* dans votre application, les descripteurs de fichiers en direct dans le noyau du système d'exploitation, généralement.

Autres conseils

La fonction standard C fflush() et le fsync() d'appel système POSIX sont conceptuellement quelque peu similaire. fflush() fonctionne sur les flux de fichiers C (objets FILE), et est par conséquent portable. fsync() agissent sur les descripteurs de fichiers POSIX. Les deux causes données en mémoire tampon à envoyer à une destination.

Sur un système POSIX, chaque flux fichier C a un descripteur de fichier associé , et toutes les opérations sur un flux de fichier C seront mises en œuvre en déléguant, le cas échéant, aux appels système POSIX qui fonctionnent sur le descripteur de fichier.

On pourrait penser qu'un appel à fflush sur un système POSIX entraînerait une write de toutes les données dans la mémoire tampon du flux de fichiers, suivi d'un appel de fsync() pour le descripteur de fichier de ce flux de fichiers. Donc, sur un système POSIX il n'y aurait pas besoin de suivre un appel à fflush avec un appel à fsync(fileno(fp)). Mais est-ce le cas: est-il un appel à fsync de fflush

Non, appelant fflush sur un système POSIX ne signifie pas que fsync sera appelée.

La norme C pour fflush dit (je souligne) il

  

que toutes les données non écrites pour [le] flux à livrer à l'environnement hôte à écrire dans le fichier

Dire que les données sont pour être écrit, plutôt que c'est écrit implique que davantage mise en mémoire tampon par l'environnement hôte est autorisé. Cette mise en mémoire tampon par le pourrait « environnement d'accueil » comprennent, pour un environnement POSIX, la mise en mémoire tampon interne qui fsync flush. Ainsi, une lecture attentive de la norme C suggère que la norme ne nécessite pas la mise en œuvre de Posix appeler fsync.

description standard POSIX fflush ne déclare pas, comme , qui fsync est appelée.

Je pourrais dire que pour la simplicité:

Utilisation fsync() avec les fichiers de streaming (descripteurs de fichier entier)

Utilisation fflush() avec des flux de fichiers.

Aussi est ici l'aide de l'homme:

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() et fsync() peuvent être utilisés pour essayer de garantir que les données sont écrites sur le support de stockage (mais il est pas toujours être possible):

  1. fflush(fp) première utilisation sur le flux de sortie (fp étant un FILE * obtenu à partir de fopen ou l'un des flux standards stdout ou stderr) pour écrire le contenu de la mémoire tampon associée au flux de l'OS.
  2. utilisez fsync(fileno(fp)) pour dire le système d'exploitation d'écrire ses propres tampons sur le support de stockage.

Notez cependant que fileno() et fsync() sont des fonctions POSIX qui pourraient ne pas être disponibles sur tous les systèmes, notamment les systèmes existants de Microsoft où les alternatives peuvent être nommés _fileno(), _fsync() ou _commit() ...

Pour forcer l'engagement des changements récents sur le disque, utilisez les fonctions de synchronisation () ou fsync ().

fsync () synchroniser toutes les données du fichier donné et métadonnées avec le dispositif de stockage permanent. Il devrait être appelé juste avant que le fichier correspondant a été fermé.

Synchronisation () engagera tous les fichiers modifiés sur le disque.

Je pense que ci-dessous le document de python ( https://docs.python.org/ 2 / bibliothèque / os.html ) clarifie très bien.

  

os.fsync (fd) écriture force de fichier avec FileDescriptor fd à disque. Sur   Unix, cela appelle la fonction native fsync (); sous Windows, MS   _commit fonction ().

     

Si vous commencez avec un objet fichier Python f, d'abord faire f.flush (),   puis faire os.fsync (f.fileno ()), afin d'assurer que tous les tampons internes   associé à f sont écrites sur le disque.

     

Disponibilité: Unix et Windows à partir de 2.2.3

.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top