IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

map d'une zone memoire en tant que fichier sous linux


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par défaut map d'une zone memoire en tant que fichier sous linux
    Bonjour,
    Je souhaite faire une opération qui s'apparente a mmap, mais a l'envers.
    En fait, j'ai déjà de la data en mémoire a une adresse allouée dans mon programme. J'aimerais plus tard dans mon programme (dans d'autres routines) attaquer cette zone mémoire a l'aide des posix open,pread,pwrite,close.

    Je ne sais pas ce genre d’opération est possible.
    Est ce que quelqu'un a une idée?
    Merci d'avance.

  2. #2
    Membre Expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Par défaut
    C'est possible il me semble...
    Il te faut peut être une extension spéciale à ton OS pour y accéder.

    Sur les Linux/BSD tu peux te renseigner sur le /dev et ses accès à la mémoire.
    Par exemple il me semble que sous FreeBSD, /dev/mem te permet cela.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  3. #3
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Bonsoir,

    pread et pwrite travaillent sur des fichiers et il leur faut un file descriptor.
    Si ton mmap mappe un fichier il n'y pas trop de problèmes (quoique ...). Mais comme tu poses la question je suppose que ton map n'est pas relié à un fichier. Je pense qu'une solution serait de créer un fichier avec le contenu de ton map. Une autre solution serait de créer un fichier au départ avec la bonne taille, le mmaper, utiliser msync le démapper puis utiliser tes routines d'accès au fichier.

    EDIT: en creusant un peu il y a peut-être la possibilité d'utiliser shm_open ... à vérifier.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par défaut
    Merci pour vos retours.
    En fait, je souhaite éviter d’écrire ce que j'ai en mémoire car ça fait potentiellement plusieurs gigas. Ensuite la raison pour laquelle je souhaite que ce fichier virtuel soit accédé par pread pwrite c'est par ce que pour une couche basse de mes routines, elles font des IO sur un fichier en mode posix pread/pwrite. Donc je voulais juste pouvoir adresser ma mémoire comme un fichier pour ne pas changer le code dans la couche basse.

    Je vais me renseigner sur ce que peut me proposer /dev

  5. #5
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Ta question m'a fait un peu chercher dans la doc ...
    shm_open peut certainement résoudre ton problème. Mais cela passe toujours par la création sous-jacente d'un fichier ; c'est plus ou moins transparent de ton point de vue. J'attache un exemple simple mélangeant accès mémoire et par fd.

    mmap.tar.gz

    L'autre solution aurait été d'utiliser fmemopen qui renvoie un stream (FILE*), et comme la man page précise :
    There is no file descriptor associated with the file stream returned by these functions (i.e., fileno(3) will return an error if called on the returned stream).
    je suppose que cela ne t'intéressera pas du tout.

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par défaut
    Ok merci pour ton code.
    Je vais essayer m'en inspirer pour voir si j'arrive a faire la chose suivante:
    • Créer le segment mémoire /dev/shm/blabla a l'aide de shm_open,... et écrire mes data dedans.

    • Puis voir si je peux l'acceder en lecture avec un posix open sur le fichier /dev/shm/blabla en lecture.


    Je test ça dans l'aprem (si je peux).
    merci encore.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par défaut
    voici ce que j'ai pu obtenir et qui semble fonctionner:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    void abort(const char* message)
    {
        perror(message);
        exit(1);
    }
     
    void read_data(const char* filename,int nb_int)
    {
        int data;
     
        int fd=open(filename,O_RDONLY);
     
        for (int i=0; i<nb_int; ++i)
        {
            pread(fd,&data,sizeof(int),sizeof(int)*i);
            printf("data[%d]=%d\n",i,data);
        }
     
        close(fd);
    }
     
    int main(int argc,char* argv[])
    {
        char filename[1024];
        char arraytmp[1024];
        const int nb_int=100;
        const int len=nb_int*sizeof(int);
        int shfd;
        int* buffer;
     
        if ((shfd=shm_open("test_rafix",O_RDWR|O_CREAT,0766))==-1)
            abort("shm_open");
     
        // Read out the link to our file descriptor
        sprintf(arraytmp,"/proc/self/fd/%d",shfd);
        memset(filename,0, sizeof(filename));
        readlink(arraytmp,filename,sizeof(filename)-1);
     
        printf("Filename : %s\n",filename);
     
        if (lseek(shfd,len-1,SEEK_SET)==-1)
            abort("lseek");
     
        if ( write(shfd,"",1)==-1)
            abort("lseek/write");
     
        if ((buffer=(int*)mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,shfd,0))==MAP_FAILED)
            abort("mmap");
     
        // from 150 to 249 in buffer
        for (int i=0; i<nb_int; ++i)
            buffer[i]=150+i;
     
        if (msync(buffer,len,MS_SYNC))
            abort("msync");
     
        // Read data in a deep part of the code...
        read_data(filename,nb_int);
     
        munmap(buffer,len);
        close(shfd);
     
        if (shm_unlink(filename)==-1)
            abort("unlink");
     
        return 0;
    }
    Est ce que j'ai l'assurance que shm_open crée bien quelque chose en mémoire et pas sur hard drive? En gros est ce aue /dev/shm c'est de la memoire?
    Je ne suis pas assez bon en linux pour le savoir. Au pire je poserai la question au boulot demain.

    Merci a tous pour votre participation.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Representation hexadecimal d'une zone memoire.
    Par etranger dans le forum C++
    Réponses: 6
    Dernier message: 13/03/2007, 14h26
  2. Fixer google map sur une zone précise ?
    Par tlafont dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 05/02/2007, 09h54
  3. Lancer une appli Java en tant que Service Windows
    Par danyboy85 dans le forum Général Java
    Réponses: 4
    Dernier message: 28/09/2006, 12h17
  4. Rendre une zone memoire accessible a un autre processus
    Par Jack_serious dans le forum POSIX
    Réponses: 12
    Dernier message: 07/12/2005, 21h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo