Qu'est-ce que la copie sur écriture?


134

Je voudrais savoir ce qu'est la copie sur écriture et à quoi sert-elle? Le terme «tableau de copie sur écriture» est mentionné plusieurs fois dans les didacticiels Sun JDK mais je n'ai pas compris ce que cela signifiait.

Réponses:


156

J'allais rédiger ma propre explication, mais cet article de Wikipedia résume assez bien la situation.

Voici le concept de base:

La copie sur écriture (parfois appelée «COW») est une stratégie d'optimisation utilisée dans la programmation informatique. L'idée fondamentale est que si plusieurs appelants demandent des ressources qui sont initialement impossibles à distinguer, vous pouvez leur donner des pointeurs vers la même ressource. Cette fonction peut être maintenue jusqu'à ce qu'un appelant essaie de modifier sa "copie" de la ressource, à quel point une véritable copie privée est créée pour éviter que les modifications ne deviennent visibles par tout le monde. Tout cela se passe de manière transparente pour les appelants. Le principal avantage est que si un appelant n'effectue aucune modification, aucune copie privée n'a jamais besoin d'être créée.

Voici également une application d'une utilisation courante de COW:

Le concept COW est également utilisé dans la maintenance des instantanés instantanés sur des serveurs de base de données comme Microsoft SQL Server 2005. Les instantanés instantanés préservent une vue statique d'une base de données en stockant une copie de pré-modification des données lorsque les données sous-jacentes sont mises à jour. Les instantanés instantanés sont utilisés pour tester des utilisations ou des rapports dépendant du moment et ne doivent pas être utilisés pour remplacer les sauvegardes.


tout ce pour quoi un tableau régulier est utilisé ... cependant, dans certaines situations, ce type de stratégie donne des résultats plus optimisés.
Andrew Flanagan

3
@hhafez: Linux l'utilise lorsqu'il l'utilise clone()pour implémenter fork()- la mémoire du processus parent est COWed pour l'enfant.
Kerrek SB

@hhafez Certains systèmes de fichiers utilisent CoW, par exemple BTRFS .
Geremia

Est-ce ainsi que fonctionne SandboxIE? lorsqu'un programme sandbox veut écraser quelque chose, sandboxie intercepte l'opération du système de fichiers et copie le fichier dans le dossier sandbox et laisse le programme écrire dans le fichier sandbox au lieu de l'original. Est-ce que cela s'appelle Copie en écriture?
Ronnie Matthews

Comment la fusion se produit-elle finalement? S'il y a N copies, laquelle est finalement conservée pour être sauvegardée sur disquette?
SimpleGuy

59

«Copier à l'écriture» signifie plus ou moins ce que cela ressemble: tout le monde a une seule copie partagée des mêmes données jusqu'à ce qu'elles soient écrites , puis une copie est faite. Habituellement, la copie sur écriture est utilisée pour résoudre les types de problèmes de concurrence. Dans ZFS , par exemple, les blocs de données sur le disque sont alloués en copie sur écriture; tant qu'il n'y a pas de changements, vous conservez les blocs d'origine; un changement n'a changé que les blocs affectés. Cela signifie que le nombre minimum de nouveaux blocs est alloué.

Ces modifications sont également généralement implémentées pour être transactionnelles , c'est-à-dire qu'elles ont les propriétés ACID . Cela élimine certains problèmes de concurrence, car vous êtes alors assuré que toutes les mises à jour sont atomiques.


1
Si vous effectuez une modification, comment l'autre est-il informé de votre nouvelle copie? Ne verraient-ils pas les mauvaises données.
poudre366

12
@ Powder366 - Non, ils ne verront pas les mauvaises données, car lorsque vous apportez une modification, c'est à ce moment qu'une copie est réellement effectuée. Par exemple, vous avez un bloc de données appelé A. Processus 1, 2, 3, 4chacun veulent faire une copie et commencer à le lire, dans une « copie à l' écriture » rien du système est copié et pourtant tout est en train de lire encore A. Désormais, le processus 3souhaite modifier sa copie de A, le processus 3va maintenant en faire une copie Aet créer un nouveau bloc de données appelé B. Processus 1, 2, 4sont encore la lecture bloc Aprocessus 3est en train de lire B.
Puddler

1
@Puddler que se passera-t-il si des modifications sont apportées dans 'A'. Tous les processus liront les informations mises à jour ou anciennes?
Développeur

3
@Developer: Eh bien, quel que soit le processus qui effectue un changement, il Adevrait créer une nouvelle copie. Si vous vous demandez ce qui se passe si un processus entièrement nouveau arrive et change, Amon explication n'est pas vraiment assez détaillée pour cela. Ce serait spécifique à l'implémentation et nécessiterait des connaissances sur la façon dont vous voulez que le reste de l'implémentation fonctionne, comme le verrouillage de fichier \ données, etc.
Puddler

10

Je ne répéterai pas la même réponse sur la copie sur écriture. Je pense que la réponse d'Andrew et la réponse de Charlie ont déjà été très clair. Je vais vous donner un exemple du monde OS, juste pour mentionner à quel point ce concept est largement utilisé.

Nous pouvons utiliser fork()ou vfork()créer un nouveau processus. vfork suit le concept de copie sur écriture. Par exemple, le processus enfant créé par vfork partagera les données et le segment de code avec le processus parent. Cela accélère le temps de fourche. Il est prévu d'utiliser vfork si vous exécutez exec suivi de vfork. Ainsi, vfork créera le processus enfant qui partagera les données et le segment de code avec son parent, mais lorsque nous appelons exec, il chargera l'image d'un nouvel exécutable dans l'espace d'adressage du processus enfant.


3
"vfork suit le concept de copie sur écriture". Veuillez envisager de modifier cette ligne. vforkn'utilise PAS COW. En fait, si l'enfant écrit quelque chose, cela peut entraîner un comportement indéfini et ne pas copier de pages !! En fait, vous pouvez dire que l'inverse est un peu vrai. COW agit comme vforkjusqu'à ce que quelque chose soit modifié dans l'espace partagé!
Pavan Manjunath

Tout à fait d'accord avec Pavan. Supprimez les lignes "vfork suit le concept de copie sur écriture". Aujourd'hui, COW est utilisé dans fork comme une optimisation, de sorte qu'il agit comme vfork et ne fasse pas de copie des données du parent pour le processus enfant (si nous appelons uniquement exec * dans child)
Shekhar Kumar

7

Pour donner un autre exemple, Mercurial utilise la copie sur écriture pour faire du clonage de référentiels locaux une opération vraiment "bon marché".

Le principe est le même que pour les autres exemples, sauf que vous parlez de fichiers physiques au lieu d'objets en mémoire. Au départ, un clone n'est pas un duplicata mais un lien dur vers l'original. Lorsque vous modifiez des fichiers dans le clone, des copies sont écrites pour représenter la nouvelle version.


2

J'ai trouvé ce bon article sur zval en PHP, qui mentionnait aussi COW:

Copy On Write (abrégé en «COW») est une astuce conçue pour économiser de la mémoire. Il est utilisé plus généralement en génie logiciel. Cela signifie que PHP copiera la mémoire (ou allouera une nouvelle région mémoire) lorsque vous écrivez sur un symbole, si celui-ci pointait déjà vers un zval.


0

Il est également utilisé dans Ruby 'Enterprise Edition' comme un moyen efficace d'économiser de la mémoire.


2
Je ne pense pas qu'il voulait dire «utilisé pour» dans ce sens.
spydon

0

Un bon exemple est Git, qui utilise une stratégie pour stocker des objets blob. Pourquoi utilise-t-il des hachages? En partie parce que ceux-ci sont plus faciles à exécuter sur les diffs, mais aussi parce que cela simplifie l'optimisation d'une stratégie COW. Lorsque vous effectuez un nouveau commit avec peu de modifications de fichiers, la grande majorité des objets et des arbres ne changeront pas. Par conséquent, le commit, à travers divers pointeurs faits de hachages, fera référence à un groupe d'objets qui existent déjà, rendant l'espace de stockage nécessaire pour stocker l'historique entier beaucoup plus petit.


0

C'est un concept de protection de la mémoire. Dans ce compilateur crée une copie supplémentaire pour modifier les données de l'enfant et ces données mises à jour ne sont pas reflétées dans les données des parents.


0

Voici une implémentation Python de copie sur écriture (COW) utilisant le modèle de conception décorateur . Une référence à un Valueobjet immuable est détenue par un CowValueobjet mutable (le décorateur). L' CowValueobjet transmet toutes les demandes de lecture à l' Valueobjet immuable et intercepte toutes les demandes d'écriture en créant un nouvel Valueobjet immuable avec l'état correct. L' CowValueobjet doit être copié superficiellement entre les variables pour permettre le partage de l' Valueobjet.

import abc
import copy

class BaseValue(abc.ABC):
    @abc.abstractmethod
    def read(self):
        raise NotImplementedError
    @abc.abstractmethod
    def write(self, data):
        raise NotImplementedError

class Value(BaseValue):
    def __init__(self, data):
        self.data = data
    def read(self):
        return self.data
    def write(self, data):
        pass

class CowValue(BaseValue):
    def __init__(self, data):
        self.value = Value(data)
    def read(self):
        return self.value.read()
    def write(self, data):
        self.value = Value(data)

v = CowValue(1)
w = copy.copy(v)  # shares the immutable Value object
assert v.read() == w.read()
assert id(v.value) == id(w.value)
w.write(2)  # creates a new immutable Value object with the correct state
assert v.read() != w.read()
assert id(v.value) != id(w.value)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.