2011-02-23 3 views
1

Je suis sur Linux 2.6 et j'ai un problème étrange. J'ai 3 processus simultanés (fourchus à partir du même processus) qui ont besoin d'obtenir 3 segments de mémoire partagée DIFFÉRENTS, un pour chaque processus. Chacun des processus exécute ce code (s'il vous plaît noter que le type « message » est défini par l'utilisateur)Comment Linux Kernel affecte-t-il des pointeurs de mémoire lorsqu'un processus utilise shm_open()?

message *m; 
    int fd = shm_open("message", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); 
    ftruncate(fd, sizeof(message)); 
    m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 
    char messagename[16]; 
    snprintf(messagename, sizeof(messagename), "%p", m); 
    char path[32] = "/dev/shm/"; 
    strcat(path, messagename); 
    rename("/dev/shm/message", path); 

Laissez-moi vous expliquer un peu: je veux que chaque processus d'allouer une zone de mémoire partagée qui contient un message. Pour m'assurer qu'un autre processus (le destinataire du message) peut accéder au même shm, je renomme ensuite mon fichier shm de "message" en une chaîne portant le nom du pointeur du message (car le processus qui le reçoit connaît déjà le pointeur). Lors de l'exécution du programme, cependant, j'ai essayé d'imprimer (à des fins de débogage) les pointeurs que chaque processus a reçu lors du mmapping du fd obtenu avec shm_open, et j'ai remarqué que tous avaient le pointeur SAME. Comment est-ce possible? J'ai pensé que peut-être d'autres processus ont fait le shm_open() après le premier et avant qu'il ait renommé le segment, donc j'ai également essayé de faire de ces lignes de code une opération atomique en utilisant un mutex partagé de processus, mais le problème persiste.

J'apprécierais vraiment toute sorte d'aide ou de suggestion.

Répondre

2

Vos processus ont tous démarré avec des dispositions d'espace d'adressage identiques au moment du forking, puis ont suivi des chemins de code très similaires. Il n'est donc pas surprenant qu'ils se retrouvent tous avec la même valeur de m.

Cependant, une fois qu'ils sont devenus des processus séparés, leurs espaces d'adressage sont devenus indépendants, afin d'avoir la même valeur de m ne signifie pas que tous les m s pointent vers la même chose.

En outre, je ne suis pas sûr que votre idée de renommer l'entrée /dev/shm après avoir créé le bloc de mémoire partagée est sûre ou portable. Si vous voulez que le bloc de mémoire partagée de chaque processus ait un nom unique, pourquoi ne pas baser le nom sur l'ID de processus (qui est garanti unique à un moment donné) et le passer directement à shm_open, plutôt que d'aller le déranger de le renommer après?

+0

Merci, votre idée d'utiliser pid semble bien et je vais certainement essayer. Cependant, grâce à shm_open(), je demande un pointeur de mémoire partagé (et non privé) et j'attendais un pointeur différent à chaque fois, indépendamment de l'espace de mémoire virtuelle du processus qui, je le pensais, n'est pas pertinent quand il s'agit de mémoire partagée . En outre, même si j'utilise un nom différent pour chacun des shm_open() appelés par les processus, ils ont tous la même adresse. Si shm_open() + mmap() donne un pointeur de mémoire partagée, comment peuvent-ils tous être identiques si le nom du shm est différent? –

+2

Tout l'accès à la mémoire d'un processus passe par l'espace d'adressage virtuel de ce processus. La mémoire sous-jacente peut être partagée, mais la vue de chaque application est privée.Il peut donc apparaître à la même adresse dans chaque processus, ou différentes adresses dans différents processus, entièrement à la discrétion de l'OS. – mhsmith

+1

... ou inversement, différents blocs de mémoire partagée peuvent apparaître à la même adresse dans différents processus, ce qui vous arrive. – mhsmith

1

La même adresse virtuelle dans différents processus peut (et habituellement) correspondre à différentes pages physiques en mémoire. Vous voudrez peut-être lire the wikipedia article on virtual memory.

+0

Merci! Je connais déjà la mémoire virtuelle. Je pensais, cependant, que même si les processus avaient des espaces mémoire différents, utiliser shm_open() et mmap() retournerait des pointeurs vers des zones partagées qui devraient être "uniques" à chaque fois. –

0

J'ai résolu un problème similaire simplement en faisant le mmap avant de forking. Donc, après le forking, la même zone est partagée entre tous les processus. J'ai ensuite mis mes sémaphores et mes mutex sur des positions définies. Cela fonctionne parfaitement.

Questions connexes