Essentiellement, j'essaie de comprendre ce qui se passe lorsque deux processus ont le même fichier ouvert en même temps, et si l'on peut l'utiliser pour offrir une communication sûre et performante entre les processus.
Si vous utilisez des fichiers normaux avec read
et write
opérations (c'est-à-dire sans les mapper en mémoire), les deux processus ne partagent aucune mémoire.
- Mémoire de l'espace utilisateur dans Java
Buffer
les objets associés au fichier ne sont PAS partagés entre les espaces d'adressage. - Quand un
write
syscall est effectué, les données sont copiées des pages dans l'espace d'adressage d'un processus aux pages dans l'espace du noyau. (Ceux-ci pourraient être des pages dans le cache de pages. C'est spécifique au système d'exploitation.) - Quand un
read
syscall est effectué, les données sont copiées des pages de l'espace du noyau aux pages de l'espace d'adressage des processus de lecture.
Cela doit être fait de cette façon. Si les pages partagées du système d'exploitation associées au lecteur et à l'écrivain traitent les tampons dans leur dos, il s'agirait alors d'une faille de sécurité/de fuite d'informations :
- Le lecteur pourrait voir les données dans l'espace d'adressage de l'auteur qui n'ont pas encore été écrites via
write(...)
, et ne le serait peut-être jamais. - Le rédacteur serait en mesure de voir les données que le lecteur a (hypothétiquement) écrites dans son tampon de lecture.
- Il ne serait pas possible de résoudre le problème en utilisant intelligemment la protection de la mémoire car la granularité de la protection de la mémoire est d'une page contre la granularité de
read(...)
etwrite(...)
qui est aussi petit qu'un seul octet.
Bien sûr :vous pouvez utiliser en toute sécurité la lecture et l'écriture de fichiers pour transférer des données entre deux processus. Mais vous auriez besoin de définir un protocole permettant au lecteur de savoir combien de données l'auteur a écrites. Et le lecteur sachant quand l'écrivain a écrit quelque chose qui pourrait entraîner des sondages ; par exemple. pour voir si le fichier a été modifié.
Si vous considérez cela uniquement en termes de copie de données dans le "canal" de communication
-
Avec les fichiers mappés en mémoire, vous copiez (sérialisez) les données des objets du tas d'application vers le tampon mappé, et une seconde fois (désérialisez) du tampon mappé vers les objets du tas d'application.
-
Avec les fichiers ordinaires, il y a deux copies supplémentaires :1) du tampon des processus d'écriture (non mappé) vers les pages de l'espace noyau (par exemple dans le cache de pages), 2) des pages de l'espace noyau vers le tampon des processus de lecture (non mappé) .
L'article ci-dessous explique ce qui se passe avec la lecture/écriture conventionnelle et le mappage de la mémoire. (C'est dans le contexte de la copie d'un fichier et de la "copie zéro", mais vous pouvez l'ignorer.)
Référence :
- Zero Copy I :Perspective du mode utilisateur