12
votes

Comment choisir une adresse fixe pour MMAP?

mmap () peut être éventuellement fourni avec un emplacement fixe pour placer la carte. J'aimerais modifier un fichier Mmeap, puis la disposer de quelques programmes différents à la même adresse virtuelle de chaque programme. Je me fiche de l'adresse, aussi longtemps qu'ils utilisent tous la même adresse. Si besoin d'être, l'adresse peut être choisie par l'une d'entre elles au moment de l'exécution (et communiquée avec les autres via certains autres moyens).

Y a-t-il une zone de mémoire que Linux garantit une utilisation inutilisée (par l'application et par le noyau) que je peux mapper? Comment trouver une adresse disponible dans plusieurs applications exécutées?


3 commentaires

Existe-t-il un problème de communication de la disposition de l'espace d'adresse de chaque programme à un maître que les syndicats sélectionnent ensuite une adresse gratuite?


Nope, cela fonctionnerait probablement. Vous auriez dû poster cela comme une réponse :-p


Je pense qu'il est assez sûr d'utiliser 0xcaffe1ne000 .


3 Réponses :


7
votes

Pas vraiment, non. Avec la randomisation de l'espace d'adressage sur les systèmes de Linux modernes, il est très difficile de garantir quoi que ce soit sur les adresses peuvent être utilisées ou non.

Également, si vous envisagez d'utiliser map_fixed , soyez conscient que vous devez faire très attention car il provoquera une implémentation de MmeAm sans quoi peut déjà être mappée à cette adresse qui est généralement une très mauvaise chose.

Je pense vraiment que vous devrez trouver une autre solution à votre problème ...


3 commentaires

+1 True, il est beaucoup préférable de penser en termes de "décalage à partir de l'adresse de base" pour stocker des données partagées, cela rend les adresses absolues fixes superflues.


@Damon pour un ensemble de données volumineux et varié n'est pas conçu à l'origine à être partagé, la modification de ces compensations en adresses réelles peut être très difficile.


De côté: map_fixed peut être utilisé en toute sécurité si vous effectuez d'abord un seul mappage sans mapper_fixed , puis utilisez mapper_fixed vers Créez diverses mappages à des adresses fixes les unes par rapport aux autres sur la cartographie d'origine d'origine située à un emplacement attribué au noyau. Avec une taille de cartographie suffisamment grande, cela pourrait résoudre le problème de l'OP.



2
votes

Vous pouvez chercher à faire un objet de mémoire partagé à l'aide de shmget () code>, shmat () code>, etc. Premièrement avoir le processus qui obtient le droit d'initialiser la mémoire partagée Objet lu dans votre fichier et copiez-le dans l'espace d'adresse d'objet de mémoire partagée. Maintenant, tout autre processus qui obtient simplement une valeur d'identification de mémoire partagée de retour peut accéder aux données dans l'espace mémoire partagé. Donc, par exemple, vous pouvez utiliser un système d'initialisation de type comme suit:

#include <sys/shm.h>

#define KEYVALUE 1000 //arbitrary value ... just needs to be shared between your processes

int file_size
//read your file and obtain its size in bytes;

//try to create the shared memory object
int shared_mem_id;
void* shared_mem_ptr = NULL;

if ((shared_mem_id = shmget(KEYVALUE, file_size, S_IRUSR | S_IWUSR IPC_CREAT | IPC_EXCL)) == -1)
{
    if (errno == EEXIST)
    {
        //shared memory segment was already created, so just get its ID value
        shared_mem_id = shmget(KEYVALUE, file_size, S_IRUSR | S_IWUSR);
        shared_mem_ptr = shmat(shared_mem_id, NULL, 0)
    }
    else
    {
        perror("Unable to create shared memory object");
        exit(1);
    }
}
else
{
    shared_mem_ptr = shmat(shared_mem_id, NULL, 0);

    //copy your file into shared memory via the shared_mem_ptr

}

//work with the shared data ...


4 commentaires

SYSV IPC (shmget / shmat) est obsolète.


@R .. Qu'est-ce qui a remplacé cette fonctionnalité? Utilise-t-il shm_open () et ftrunate () avec mmap () ?


Oui. Ou même utiliser des fichiers ordinaires plutôt que shm_open si vous préférez (cela vous donne une légère meilleure capacité à contrôler les autorisations et à tous, mais avec un risque de gaspillage de ressources, rincer les données sur disque).


@R .. Lorsque vous dites d'utiliser des "fichiers ordinaires", vous parlez de la mémoire-la mappe de la mémoire, cependant de mmap () , non?



5
votes

Deux procédés peuvent mapper un bloc de mémoire partagé sur la même adresse virtuelle à l'aide de shm_open () et de MMAP (); C'est-à-dire que l'adresse virtuelle renvoyée de MMAP () peut être la même pour les deux processus. J'ai trouvé que Linux sera par défaut donnant différentes adresses virtuelles à différents processus pour la même pièce de mémoire partagée, mais que l'utilisation de MMAP () avec MAP_FIXED obligera Linux à fournir la même adresse virtuelle à plusieurs processus.

Le processus qui crée le bloc de mémoire partagé doit stocker l'adresse virtuelle quelque part dans la mémoire partagée, dans un fichier ou avec une autre méthode de sorte qu'un autre processus puisse déterminer l'adresse virtuelle d'origine. L'adresse virtuelle connue est ensuite utilisée dans l'appel MMAP (), avec le drapeau MAP_FIXED.

J'ai pu utiliser la mémoire partagée pour le faire. Ce faisant, l'adresse virtuelle "Golden" est stockée dans le bloc de mémoire partagé; J'ai fait une structure contenant un certain nombre d'articles, l'adresse étant l'une d'entre elles et l'initialisée au début du bloc.

Un processus qui souhaite mapper cette mémoire partagée doit exécuter la fonction MMAP () deux fois; Une fois pour obtenir l'adresse virtuelle "Golden", puis modifier le bloc à cette adresse à l'aide du drapeau map_fixed.

Fait intéressant, je travaille avec un système intégré exécutant un 2,6 noyau. Par défaut, il fournira la même adresse virtuelle à tous les appels MMAP () à un descripteur de fichier donné. Aller chiffre.

BOB WIRKA


1 commentaires

Je suis également ennuyé par le fait que mmap donne différentes adresses pour la même pièce de mémoire partagée. Dans une tentative de contourner cela, j'ai essayé d'utiliser map_fixed . Mais cela ne fonctionne pas ... Comment l'avez-vous fait fonctionner? Veuillez ajouter un exemple de code à votre réponse. Voir aussi Stackoverflow.com/Questtions/50093733