Utilisez VirtualProtect pour marquer les pages en tant que copie sur écriture (fourche de pauvre homme sur Windows)

J’utilise VirtualAlloc (Ex) pour allouer et valider un large éventail de pages.

Plus tard au cours de l’exécution, je souhaite “répartir” cette mémoire, lancer un nouveau processus capable de le lire dans son état actuel, tandis que le processus parent le traite comme de la mémoire de copie sur écriture.

Cela peut-il être fait avec VirtualAlloc (Ex) et VirtualProtect (Ex)?

Ceci est sortingvial sur les systèmes posix grâce à fork (). Puis-je émuler efficacement cette partie de la fourche sur Windows?

Merci, -Dan

Je ne crois pas que l’un d’entre eux réponde assez bien à la question posée par l’affiche originale. Je pourrais peut-être prendre l’exemple suivant. Supposons que l’on ait des données dans “bufferA” et que l’on les copie dans “bufferB”, puis modifie les deux tampons. Maintenant, on examine les deux tampons et décide de copier “bufferA” ou “bufferB” dans “bufferC” et d’apporter plus de modifications à “bufferC”, etc.

En supposant que les tampons sont volumineux et que les modifications sont petites, la question est de savoir si ce serait une optimisation d’utiliser la fonctionnalité de copie en écriture du MMU sur la machine hôte et s’il existe une API pour permettre cela.

L’utilisation de fichiers mappés en mémoire ne fonctionne pas tout à fait car, une fois qu’on utilise PAGE_WRITECOPY, il ne semble pas y avoir de moyen de dire “maintenant copier les pages virtuelles contenant les modifications”. Par exemple, si “bufferA” et “bufferB” étaient tous deux des mappages du même fichier, l’un d’entre eux était marqué “WRITECOPY” au moment du mappage. On peut bien sûr copier les bits, mais la question est de savoir s’il existe une optimisation potentielle.

Il existe une fonction appelée VirtualCopy (), mais qui semble être spécifique à Windows CE et fonctionne avec des adresses physiques. La question ici est de savoir s’il existe quelque chose comme “VirtualCopy”, mais en prenant une adresse virtuelle comme source.

Notez que bien que “fork ()” (sur les systèmes qui l’ont) le fasse, un “fork” “tout le processus, pas seulement le tampon. Il y avait une discussion connexe concernant “copy-on-write memcpy” ici ( Puis-je faire un memcpy de copie sur écriture sous Linux? ).

Ainsi, l’API recherchée pourrait ressembler à ceci: void * VirualCopyVirtualAddressSpace (void * src, size_t length);

Jusqu’à présent, je n’ai vu aucune API sur aucun système permettant de copier les tampons dans un processus ou entre des processus existants. Bien que je ne sois pas un expert, j’aurais pensé que copier un segment de mémoire virtuelle correctement aligné via le mécanisme de copie sur écriture serait raisonnablement simple, du moins dans un seul espace d’adressage.

Je pense que vous pouvez le faire si vous utilisez le mappage de mémoire (CreateFileMapping / MapViewOfFile) avec PAGE_WRITECOPY.

Cet exemple dans MSDN peut servir de sharepoint départ si vous remplacez FILE_MAP_ALL_ACCESS par PAGE_WRITECOPY pour le deuxième processus.

Si vous voulez un comportement cohérent au sharepoint copie, vous aurez probablement besoin de VirtualProtect () la région mappée avec PAGE_WRITECOPY dans le premier processus, donc le second processus ne voit aucune modification.