Comment la copie sur écriture dans fork () gère-t-elle plusieurs fork?

23

Selon Wikipedia (ce qui pourrait être faux)

Lorsqu'un appel système fork () est émis, une copie de toutes les pages correspondant au processus parent est créée, chargée dans un emplacement mémoire séparé par le système d'exploitation pour le processus enfant. Mais cela n'est pas nécessaire dans certains cas. Considérez le cas où un enfant exécute un " exec" appel système (qui est utilisé pour exécuter n'importe quel fichier exécutable depuis un programme C) ou se termine très peu de temps après fork(). Lorsque l'enfant est nécessaire uniquement pour exécuter une commande pour le processus parent, il n'est pas nécessaire de copier les pages du processus parent, car execremplace l'espace d'adressage du processus qui l'a invoqué par la commande à exécuter.

Dans de tels cas, une technique appelée copie sur écriture (COW) est utilisée. Avec cette technique, lorsqu'un fork se produit, les pages du processus parent ne sont pas copiées pour le processus enfant. Au lieu de cela, les pages sont partagées entre l'enfant et le processus parent. Chaque fois qu'un processus (parent ou enfant) modifie une page, une copie distincte de cette page particulière seule est créée pour ce processus (parent ou enfant) qui a effectué la modification. Ce processus utilisera alors la page nouvellement copiée plutôt que celle partagée dans toutes les références futures. L'autre processus (celui qui n'a pas modifié la page partagée) continue d'utiliser la copie d'origine de la page (qui n'est plus partagée maintenant). Cette technique est appelée copie sur écriture car la page est copiée lorsqu'un processus y écrit.

Il semble que lorsque l'un des processus tente d'écrire sur la page, une nouvelle copie de la page est allouée et affectée au processus qui a généré l'erreur de page. La page d'origine est marquée en écriture par la suite.

Ma question est: que se passe-t-il si le fork()obtient appelé plusieurs fois avant que l'un des processus ne tente d'écrire sur une page partagée?

ssgao
la source
Wikipédia a raison dans ce cas, juste un niveau plus élevé.
Didi Kohen
1
Oui, la copie sur écriture est une copie paresseuse, le processus enfant copie la page lorsque vous essayez de l'écrire. Donc, fondamentalement, après une fourchette, presque la mémoire de l'enfant est partagée avec le parent. Cependant, avant tout processus effectué, chaque processus enfant a toujours de la mémoire privée, modifiée à partir de l'allocation parent ou nouvelle. Cela signifie que même sans aucune action, le processus enfant forké a une certaine mémoire privée. Nous pouvons le vérifier avec pmap -XX PIDou cat /proc/PID/smap.
where23
En ce qui concerne - "La page d'origine est marquée en écriture par la suite.", Qui en sera propriétaire? Voici l'autre processus qui n'a pas essayé de l'écrire?
Adil
C'est adorable. Commençons à enseigner cela dans les jardins d'enfants
ed22

Réponses:

18

Rien de particulier ne se produit. Tous les processus partagent le même ensemble de pages et chacun obtient sa propre copie privée lorsqu'il souhaite modifier une page.

jlliagre
la source
Droite. Le fait est que c'est le processus enfant qui est spécial, qui a la tâche de copier s'il essaie d'écrire sur la page partagée. Ni le parent ni les autres enfants n'ont besoin de connaître le changement s'il est fait correctement.
Charles Stewart
9
Le processus enfant n'est pas si spécial. Les processus enfant et parent ont tous deux le même ensemble de pages en lecture seule après le fork. En ce qui concerne ces pages, la gestion des pages est symétrique.
jlliagre
3

Le comportement de fork () varie selon que le système * nix a une MMU ou non. Sur un système non-MMU (comme les premiers PDP-11), l'appel système fork () a copié toute la mémoire du parent pour chaque enfant. Sur un système * nix basé sur MMU, le noyau marque toutes les pages non empilées comme R / O et les partage entre le parent et l'enfant. Ensuite, lorsque l'un des processus écrit sur une page, la MMU intercepte la tentative, le noyau alloue ensuite une page accessible en écriture et met à jour les tables de pages MMU pour pointer vers la page désormais accessible en écriture. Ce comportement de copie sur écriture offre une accélération car initialement, seule une pile privée doit être allouée et clonée pour chaque processus enfant.

Si vous exécutez du code parent entre chaque appel fork (), les processus enfants résultants diffèrent par les pages qui ont été modifiées par le parent. D'un autre côté, si le parent émet simplement plusieurs appels fork (), par exemple dans une boucle, alors les processus enfants seront presque identiques. Si une variable de boucle locale est utilisée, elle sera différente dans la pile de chaque enfant.

CyberFonic
la source
0

Lorsque le système exécute un fork, généralement (cela peut dépendre de l'implémentation), il marque également les pages en lecture seule et marque le processus parent comme maître de ces pages.
Lorsque vous essayez d'écrire sur ces pages, une erreur de page se produit et le système d'exploitation prend le relais, copiant la liste entière des pages ou uniquement les pages modifiées (encore une fois, en fonction de l'implémentation), de sorte que le processus d'écriture aura une copie inscriptible.
Lorsqu'il existe plusieurs processus issus du même, lorsque le processus "maître" écrit dans sa mémoire, les autres processus obtiennent leurs pages équivalentes copiées.

Didi Kohen
la source
quel système fait cela? linux utilise une implémentation de copie sur écriture
brauliobo
Voilà comment fonctionne la copie sur écriture ...
Didi Kohen
3
@DavidKohen ce n'est pas ainsi que fonctionne la copie sur écriture dans n'importe quelle version de celui-ci dont j'ai jamais entendu parler. Il n'y a pas de processus "maître". Si un processus unique écrit les pages partagées, sa copie est transférée sur une page privée tandis que tous les autres processus continuent de la partager.
Celada
1
Je pense que David Kohen a raison à un moment donné. C'est une façon d'implémenter la copie sur écriture. L'essentiel serait qu'avec ce marquage, l'écriture sur cette page déclencherait un gestionnaire de défauts de page qui prendrait alors les mesures appropriées, c'est-à-dire la copie sur écriture. Malheureusement, ce détail (qui serait spécifique au système) est généralement hors de propos pour la question. Gardez à l'esprit que CoW a deux dimensions: celle visible par le processus et celle de la façon dont le noyau pourrait l'implémenter.
0xC0000022L