Question

En général, que pouvons-nous prendre pour acquis lorsque nous joignons à un fichier sous UNIX à partir de plusieurs processus? Est-il possible de perdre des données (un processus de changements avec écrasements l'autre)? Est-il possible pour les données pour obtenir déchiquetés? (Par exemple, chaque processus est l'ajout d'une ligne par append à un fichier journal, est-il possible que deux lignes se déchiquetés?) Si l'append n'est pas atomique dans le sens ci-dessus, quelle est la meilleure façon d'assurer l'exclusion mutuelle?

Était-ce utile?

La solution

Une écriture qui est sous la taille de « PIPE_BUF » est censé être atomique. Cela devrait être d'au moins 512 octets, mais il pourrait facilement être plus grand (linux semble avoir mis en 4096).

supposons que vous parlez tous les composants entièrement compatibles POSIX. Par exemple, ce n'est pas vrai sur NFS.

Mais en supposant que vous écrivez à un fichier journal que vous avez ouvert en mode « O_APPEND » et gardez vos lignes (y compris saut de ligne) sous octets « PIPE_BUF » longtemps, vous devriez être en mesure d'avoir plusieurs auteurs à un fichier journal sans aucun problème de corruption. Toutes les interruptions arriveront avant ou après l'écriture, pas au milieu. Si vous voulez l'intégrité des fichiers pour survivre à un redémarrage, vous aurez également besoin d'appeler fsync(2) après chaque écriture, mais c'est terrible pour la performance.

Précision : lire les commentaires et les Oz réponse de Salomon. Je ne suis pas sûr que O_APPEND est censé avoir cette taille de PIPE_BUF atomicité. Il est tout à fait possible que c'est à quel point Linux mis en œuvre write(), ou il peut être dû à des tailles de bloc du système de fichiers sous-jacent.

Autres conseils

Edit:. Mise à jour Août 2017 derniers résultats de Windows

Je vais vous donner une réponse avec des liens pour tester le code et les résultats que l'auteur de projet Boost.AFIO qui implémente un système de fichiers asynchrone et le fichier i / o C ++ bibliothèque.

Tout d'abord, O_APPEND ou le FILE_APPEND_DATA équivalent sur Windows signifie que les incréments de l'étendue maximale de fichier (fichier « longueur ») sont atomique en vertu auteurs simultanés. Ceci est garanti par POSIX et Linux, FreeBSD, OS X et Windows tout mettre en œuvre correctement. Samba met également en œuvre correctement, NFS avant v5 ne pas comme il n'a pas la capacité de format de fil pour ajouter atomiquement. Donc, si vous ouvrez votre fichier avec append-only, écritures concurrentes ne se déchire pas par rapport à l'autre sur tout système d'exploitation majeur à moins que NFS est impliqué.

Cependant en même temps lit à ajouter ses atomiques peut voir déchiré écrit selon le système d'exploitation, système de classement, et ce que les drapeaux que vous avez ouvert le fichier avec - l'augmentation de l'étendue maximale du fichier est atomique, mais la visibilité des écritures par rapport à lit peut ou non être atomique. Voici un résumé rapide des drapeaux, OS et système de classement:


Non O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 avec NTFS. Mise à jour atomicité = 1 octet jusqu'à et y compris 10.0.10240, de 10.0.14393 au moins 1Mb, probablement infini (*)

Linux 4.2.6 avec ext4: mise à jour atomicité = 1 octet

FreeBSD 10.2 avec ZFS: mise à jour atomicité = au moins 1Mb, probablement infini (*)

O_DIRECT / FILE_FLAG_NO_BUFFERING:

Microsoft Windows 10 avec NTFS: mise à jour atomicité = jusqu'à et y compris 10.0.10240 jusqu'à 4096 octets seulement si la page aligné, sinon 512 octets si FILE_FLAG_WRITE_THROUGH off, sinon 64 octets. Notez que cette atomicité est probablement une caractéristique de PCIe DMA plutôt que conçu. Depuis 10.0.14393, au moins 1Mb, probablement infini (*).

Linux 4.2.6 avec ext4: mise à jour atomicité = au moins 1Mb, probablement infinie (*). Notez que plus tôt avec ext4 Linux peuvent certainement ne dépassent pas 4096 octets, XFS certainement l'habitude d'avoir de verrouillage sur mesure, mais il semble que Linux récente a finalement résolu ce.

FreeBSD 10.2 avec ZFS: mise à jour atomicité = au moins 1Mb, probablement infini (*)


Vous pouvez voir les résultats des tests empiriques premières à https: // github .com / ned14 / afio / arbre / maître / programmes / fs-sonde . Notez que nous testons les décalages que sur 512 déchirés multiples octets, donc je ne peux pas dire si une mise à jour partielle d'un secteur de 512 octets déchirerait pendant le cycle d'écriture de lecture-modification.

Donc, pour répondre à la question de l'OP, O_APPEND écrit ne gêne pas l'autre, mais se lit en même temps à O_APPEND écritures va probablement voir déchiré écrit sur Linux avec ext4 à moins O_DIRECT est, après quoi vos écritures de O_APPEND auraient besoin d'être un secteur taille multiple.


(*) "Probablement infini" découle de ces clauses dans les spécifications POSIX:

  

sera atomique Toutes les fonctions suivantes par rapport à chaque   autre dans les effets spécifiés dans POSIX.1-2008 lorsqu'ils fonctionnent sur   fichiers réguliers ou des liens symboliques ... [nombreuses fonctions] ... read () ...   écrire () ... Si deux fils chaque appel une de ces fonctions, chaque appel   sont soit voir tous les effets spécifiques de l'autre appel, ou   aucun d'entre eux. [Source]

et

  

Rédige peuvent être sérialisés par rapport aux autres lectures et écritures. Si un   read () de données de fichiers peut être prouvée (par tout moyen) de se produire après un   écrire () des données, il doit tenir compte de cette écriture (), même si les appels   sont faites par différents procédés. [Source]

mais à l'inverse:

  

Ce volume de POSIX.1-2008 ne spécifie pas le comportement de concurrent   écrit dans un fichier à partir de plusieurs processus. Les applications doivent utiliser certains   sous forme de contrôle de concurrence. [Source]

Vous pouvez en savoir plus sur la signification de ces derniers dans cette réponse

J'ai écrit un script pour tester empiriquement la taille de append atomique maximale. Le script, écrit en bash, engendre plusieurs processus de travail qui écrivent tous les signatures spécifiques de travailleurs dans le même fichier. Il lit ensuite le fichier, à la recherche de signatures qui se chevauchent ou corrompus. Vous pouvez voir la source pour le script à ce .

La taille de l'ajout atomique maximale réelle varie non seulement par OS, mais par le système de fichiers.

Linux + ext3 la taille est 4096, et sur Windows + NTFS la taille est 1024. Voir les commentaires ci-dessous pour plus de tailles.

Voici ce que dit la norme: http://www.opengroup.org /onlinepubs/009695399/functions/pwrite.html .

  

Si le drapeau O_APPEND des indicateurs d'état de fichier est défini, le fichier de la compensation est fixé à la fin du fichier avant chaque écriture et aucune opération de modification du fichier intervenant doit se produire entre la modification du fichier offset et l'opération d'écriture.

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