Que fait exactement le file.flush () de Python?

137

J'ai trouvé ceci dans la documentation Python pour les objets fichier :

flush () n'écrit pas nécessairement les données du fichier sur le disque. Utilisez flush () suivi de os.fsync () pour garantir ce comportement.

Ma question est donc: que fait exactement Python flush? Je pensais que cela obligeait à écrire des données sur le disque, mais maintenant je vois que ce n'est pas le cas. Pourquoi?

geek
la source

Réponses:

220

Il y a généralement deux niveaux de mise en mémoire tampon impliqués:

  1. Tampons internes
  2. Tampons du système d'exploitation

Les tampons internes sont des tampons créés par le runtime / la bibliothèque / le langage avec lequel vous programmez et sont destinés à accélérer les choses en évitant les appels système à chaque écriture. Au lieu de cela, lorsque vous écrivez dans un objet fichier, vous écrivez dans sa mémoire tampon, et chaque fois que la mémoire tampon se remplit, les données sont écrites dans le fichier réel à l'aide d'appels système.

Cependant, en raison des tampons du système d'exploitation, cela peut ne pas signifier que les données sont écrites sur le disque . Cela peut simplement signifier que les données sont copiées des tampons maintenus par votre runtime dans les tampons maintenus par le système d'exploitation.

Si vous écrivez quelque chose et qu'il se retrouve dans la mémoire tampon (uniquement) et que l'alimentation de votre machine est coupée, ces données ne sont pas sur le disque lorsque la machine s'éteint.

Donc, pour vous aider, vous disposez des méthodes flushet fsync, sur leurs objets respectifs.

Le premier flush,, écrira simplement toutes les données qui persistent dans un tampon de programme dans le fichier réel. Cela signifie généralement que les données seront copiées du tampon du programme vers le tampon du système d'exploitation.

Plus précisément, cela signifie que si un autre processus a ce même fichier ouvert en lecture, il pourra accéder aux données que vous venez de rincer dans le fichier. Cependant, cela ne signifie pas nécessairement qu'il a été stocké «en permanence» sur le disque.

Pour ce faire, vous devez appeler la os.fsyncméthode qui garantit que tous les tampons du système d'exploitation sont synchronisés avec les périphériques de stockage auxquels ils sont destinés, en d'autres termes, cette méthode copiera les données des tampons du système d'exploitation sur le disque.

En règle générale, vous n'avez pas besoin de vous soucier de l'une ou l'autre des méthodes, mais si vous êtes dans un scénario où la paranoïa sur ce qui se termine réellement sur le disque est une bonne chose, vous devez effectuer les deux appels comme indiqué.


Addendum en 2018.

Notez que les disques avec des mécanismes de cache sont maintenant beaucoup plus courants qu'en 2013, il y a donc encore plus de niveaux de mise en cache et de tampons impliqués. Je suppose que ces tampons seront également gérés par les appels sync / flush, mais je ne sais pas vraiment.

Lasse V. Karlsen
la source
10
Lorsque j'utilise la with file('blah') as fd: #dostuffconstruction, je sais qu'elle garantit la fermeture du descripteur de fichier. Est-ce qu'il est également vidé ou synchronisé?
Marcin
3
@Marcin: Il vide, mais ne se synchronise PAS.
Alex I
8
fsyncest nécessaire pour l'atomicité. vous ne pouvez pas vous attendre à fermer un fichier, à le rouvrir et à trouver votre contenu sans un fsyncau milieu. Cela fonctionne souvent, mais ce n'est pas le cas sous linux avec ext4 et les options de montage par défaut par exemple. Il fsyncn'est pas non plus garanti de retourner le fer à repasser sur les plateaux, car 1: fsync peut être désactivé (en mode ordinateur portable) et 2: la mise en mémoire tampon interne du disque dur peut ne pas être chargée de vider.
v.oddou
1
existe-t-il un moyen de vider la mémoire tampon d'un système d'exploitation pour tous les fichiers, si le fichier est écrit par un autre processus?
Nacht
1
fsync est relativement cher. En général, vous n'écrivez pas de logiciels critiques qui nécessitent une conformité et une durabilité à 100% ACID pour l'accès au disque, et si vous le faites, vous en êtes probablement douloureusement conscient et devez être conscient des étapes que vous pouvez prendre pour obtenir ces garanties. . L'appel de fsync attendra que l'accès au disque physique se produise pour écrire les données sur le disque, tandis que le vidage et la fermeture n'attendront que les données à déplacer vers la mémoire cache. La différence de vitesse est probablement de plusieurs ordres de grandeur.
Lasse V. Karlsen
10

Parce que le système d'exploitation peut ne pas le faire. L'opération de vidage force les données de fichier dans le cache de fichiers dans la RAM, et à partir de là, c'est le travail du système d'exploitation de les envoyer réellement sur le disque.

Ignacio Vazquez-Abrams
la source
6
Vous avez raison, mais actuallyc'est relatif ici: si la mise en cache d'écriture est activée sur le périphérique cible, les données peuvent ne pas avoir atteint les plateaux / puces réels lors du os.fsync()retour.
Frédéric Hamidi
7

Il vide le tampon interne, ce qui est censé amener le système d'exploitation à écrire le tampon dans le fichier. [1] Python utilise la mise en mémoire tampon par défaut du système d'exploitation, sauf si vous le configurez autrement.

Mais parfois, le système d'exploitation choisit toujours de ne pas coopérer. Surtout avec des choses merveilleuses comme les retards d'écriture dans Windows / NTFS. Fondamentalement, le tampon interne est vidé, mais le tampon du système d'exploitation le tient toujours. Vous devez donc dire au système d'exploitation de l'écrire sur le disque avec os.fsync()dans ces cas.

[1] http://docs.python.org/library/stdtypes.html

Dan
la source
0

Fondamentalement, flush () nettoie votre mémoire tampon RAM, son vrai pouvoir est qu'il vous permet de continuer à y écrire par la suite - mais cela ne devrait pas être considéré comme la meilleure / la plus sûre fonctionnalité d'écriture dans un fichier. C'est vider votre RAM pour plus de données à venir, c'est tout. Si vous voulez vous assurer que les données sont écrites dans le fichier en toute sécurité, utilisez plutôt close ().

zA.
la source