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 :

Différence entre mmap() et read()


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 274
    Par défaut Différence entre mmap() et read()
    Bonjour à tous,

    voila si je veux lire un fichier je peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int fd = open("fichier_a_lire.txt", O_RDONLY);
    et ensuite je peux faire :
    ou faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    void* addr = mmap(NULL,length_of_fichier_a_lire,…, fd, 0);
    strncpy( buffer, addr, 256);
    mais c'est quoi le mieux?
    dans les deux cas le fichier est chargé en RAM par le noyau via l'appel système open, donc pourquoi s’embêter avec mmap ?

    merci de vos éclaircissements

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par cosmoff Voir le message
    dans les deux cas le fichier est chargé en RAM par le noyau via l'appel systeme open
    Perdu

    Quand tu lis un fichier via open(), une partie du fichier est chargée en mémoire pour économiser les accès disques (bufferisation) donc les lectures suivantes se font depuis le buffer mémoire ok. Mais déjà la bufferisation ne concerne qu'une portion du fichier (portion équivalente à la taille du buffer) et d'autre part, du point de vue programme, la lecture par read(), même si elle est faite depuis le buffer, est quand-même considérée comme se faisant depuis un fichier disque.

    Bien entendu, si le fichier est assez petit, alors effectivement la différence devient négligeable (si tout le fichier est chargé dans le buffer les read seront très rapide) mais tu ne peux pas implémenter un choix technique en te fondant sur la chance.

    Donc si ton algorithme n'a besoin que d'un caractère, ou 10 ou 100 en séquentiel, alors tu pars sur open()+read() et si ton algo a besoin de tout le fichier en RAM, alors nmap(). Mais dans ce cas il faut vraiment que le besoin soit réellement justifié (comme par exemple tu as besoin de te ballader super souvent et super rapidement à différentes positions du fichier aussi bien avant que arrière) parce que charger tout un fichier en RAM ça peut vite devenir gourmand...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Justement, ou alors je n'ai pas saisi ce que tu as exprimé Sve@r : l'intérêt d'mmap un fichier est de produire une vue de son contenu en mémoire système. Cela permet à l'application de faire comme si elle disposait d'un buffer gigantesque alors que le kernel réalise une transposition d'adresse et charge et décharge à la volée les pages requises.

    Lorsque l'on read, les données sont a priori réellement chargées en mémoire.

  4. #4
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    18 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 18 284
    Par défaut
    mmap permet de charger un fichier complet dans l'espace d'adressage d'un processus. L’intérêt par rapport à fopen/read est de pouvoir se balader comme on veut dedans. Pour des fichiers standards, l’intérêt est faible, surtout que je pense que mmap utilise le système du copy on write ce qui peut être dangereux en cas d'erreur IO, plus facilement contrôlable par la famille des fonctions fopen/fread.

    L’intérêt de mmap est aussi de pouvoir changer les droits d'accès lors du chargement (exemple zone de code au lieu de données), nécessaire pour charger du code exécutable par exemple. Les fonctions execve utilisent mmap (la page de man fait référence à exec, et fork notamment)

    Tu peux considérer mmap comme une façon exotique de charger un fichier en mémoire. A ne pas faire si on ne maitrise pas ce qu'on fait.
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur le P2V, mon article sur le cloud
    Consultez nos FAQ : Windows, Linux, Virtualisation

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Lorsque l'on read, les données sont a priori réellement chargées en mémoire.
    Oui parce que le read() est limité à 32767 caractères donc ces 32767 caractères sont réellement chargés dans la RAM. Alors que le fichier chargé par mmap() est probablement chargé dans la RAM+SWAP.

    Mais j'ai aussi parlé de "se ballader super souvent et super rapidement à différentes positions du fichier aussi bien avant que arrière". Si ton fichier est chargé en RAM (que ce soit en vraie RAM ou en SWAP pour le programmeur ça reste de la RAM), tu peux traiter le premier caractère, puis le dernier, puis le second, puis l'avant-dernier et etc (par exemple : tester que le contenu d'un fichier est un palindrome).
    Tu peux obtenir le même résultat à base de tell() + seek() + read() mais ça sera 1000 fois plus long (ne serait-ce par exemple; que parce que le fichier est trop gros pour tenir entièrement dans le buffer donc si tu lis le premier caractère, puis le dernier, puis le second et etc alors à chaque lecture le fichier sera réellement pris depuis le disque dur).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre très actif
    Homme Profil pro
    Inscrit en
    Août 2013
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2013
    Messages : 274
    Par défaut
    merci beaucoup pour vos réponses tres completes.

    donc quand je fais open(), le noyau va juste regarder si le fichier existe et mettre à jour sa table de descriptor de fichier, il ne charge pas le fichier en RAM. Il ne charge les data que lorsque je fais un read(fd, buffer, 256), et il charge un nombre de caractere correspondant à 256 dans mon exemple

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 840
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par cosmoff Voir le message
    donc quand je fais open(), le noyau va juste regarder si le fichier existe et mettre à jour sa table de descriptor de fichier,
    Probablement (encore que le fichier peut ne pas exister et sera créé si tu as demandé l'option "O_CREAT")...

    Citation Envoyé par cosmoff Voir le message
    il ne charge pas le fichier en RAM.
    Là c'est sûr que non

    Citation Envoyé par cosmoff Voir le message
    Il ne charge les data que lorsque je fais un read(fd, buffer, 256), et il charge un nombre de caractere correspondant à 256 dans mon exemple
    Exact. Même s'il est quasi certain qu'il va en charger beaucoup plus dans le buffer IO en prévision des read() suivants, toi (progammeur) tu n'en as que 256 à ta disposition immédiate.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Je ne te suis pas Sve@r. Lorsque tu mmap le fichier, la présence réelle des données en mémoire système est entièrement à la discrétion du kernel. Tu pourrais très bien lire ou écrire partout dans le fichier de manière aléatoire - c'est d'ailleurs un cas d'usage bien connu de mmap - en ne disposant à tout moment que d'une seule page chargée en mémoire, et ce serait tout aussi transparent pour l'application (exceptées les horrible perfs qui en découleraient ). Quant à parler de swap, c'est incongru ici.

    Je n'ai pas connaissance de cette limite de 2^15 pour read, c'est sensé être quoi ? La taille du buffer ? Je serais surpris que POSIX impose un truc aussi arbitraire.

Discussions similaires

  1. Différences entre Delphi et Visual Basic ?
    Par Anonymous dans le forum Débats sur le développement - Le Best Of
    Réponses: 75
    Dernier message: 30/03/2009, 20h09
  2. La difference entre XSL et XSLT?
    Par pantin dans le forum XSL/XSLT/XPATH
    Réponses: 3
    Dernier message: 27/06/2003, 15h14
  3. Difference entre fenetre et boite de dialog
    Par billyboy dans le forum Windows
    Réponses: 2
    Dernier message: 02/06/2003, 15h43
  4. [] Difference entre MSHFlexGrid et MSFlexGrid
    Par olivierx dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 23/04/2003, 08h48
  5. Difference entre types d'Adresse IP
    Par freud dans le forum Développement
    Réponses: 3
    Dernier message: 02/03/2003, 02h06

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