2015-12-02 12 views
6

man पृष्ठ से,एमएमएपी सिस्टम कॉल में MAP_ANONYMOUS ध्वज का उद्देश्य क्या है?

MAP_ANONYMOUS 
       The mapping is not backed by any file; its contents are initialized to zero. The fd and offset arguments are ignored; however, some implementations require 
       fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and portable applications should ensure this. The use of MAP_ANONYMOUS in conjunction with 
       MAP_SHARED is only supported on Linux since kernel 2.4. 

MAP_ANONYMOUS का उपयोग करने का उद्देश्य क्या है? कोई भी उदाहरण अच्छा होगा। इसके अलावा स्मृति कहाँ मैप किया जाएगा?

यह man पृष्ठ पर लिखा है कि The use of MAP_ANONYMOUS in conjunction with MAP_SHARED is only supported on Linux since kernel 2.4. कैसे मैं स्मृति अन्य प्रक्रिया के साथ MAP_ANONYMOUS साथ मैप की साझा कर सकते हैं?

उत्तर

11

बेनामी मैपिंग को शून्यकृत वर्चुअल फ़ाइल के रूप में चित्रित किया जा सकता है। बेनामी मैपिंग बस उपयोग के लिए तैयार मेमोरी के बड़े, शून्य भरे ब्लॉक हैं। ये मैपिंग ढेर के बाहर रहते हैं, इस प्रकार डेटा सेगमेंट विखंडन में योगदान नहीं देते हैं।

MAP_ANONYMOUS + MAP_PRIVATE:

  • हर कॉल
  • बच्चों माता पिता की मैपिंग
  • बच्चों के वारिस एक अलग मानचित्रण बनाता है 'विरासत में मिला मानचित्रण पर लिखता है प्रति-ऑन-राइट ढंग से catered रहे
  • इस प्रकार के मैपिंग का उपयोग करने का मुख्य उद्देश्य एक नई शून्यकृत मेमोरी आवंटित करना है
  • malloc अज्ञात प्राइ MMAP_THRESHOLD बाइट्स से बड़े स्मृति आवंटन अनुरोधों को पूरा करने के लिए vate mappings।
    आम तौर पर, MMAP_THRESHOLD 128kB है।

MAP_ANONYMOUS + MAP_SHARED:

  • eah कॉल एक अलग मानचित्रण कि किसी अन्य मानचित्रण
  • बच्चों माता पिता की मैपिंग के वारिस
  • कोई कॉपी-ऑन के साथ पृष्ठ साझा नहीं करता बनाता है लिखें जब मैपिंग साझा करने वाला कोई अन्य व्यक्ति साझा मैपिंग
  • साझा अज्ञात मैपिंग्स पर अनुमति देता है I एक तरीके से पीसी सिस्टम वी स्मृति क्षेत्रों के लिए समान है, लेकिन केवल संबंधित प्रक्रियाओं

लिनक्स पर, वहाँ गुमनाम मैपिंग बनाने के लिए दो तरीके हैं के बीच:

  • MAP_ANONYMOUS ध्वज को निर्दिष्ट और पारित -1 fd के लिए

    addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 
        if (addr == MAP_FAILED) 
         exit(EXIT_FAILURE); 
    
  • खुला/dev/शून्य और पास इस fd

    fd = open("/dev/zero", O_RDWR); 
        addr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); 
    
    खोला

गुमनाम मैपिंग के लाभ (इस विधि आम तौर पर बीएसडी जैसी प्रणालियों, कि MAP_ANONYMOUS झंडा नहीं है पर प्रयोग किया जाता है):
- कोई वर्चुअल ऐड्रेस स्पेस विखंडन; unmapping के बाद, स्मृति तुरंत प्रणाली
में लौट आता है - वे आवंटन आकार, अनुमतियों के मामले में परिवर्तनीय हैं और वे भी बस सामान्य मैपिंग की तरह सलाह प्राप्त कर सकते हैं
- प्रत्येक आवंटन एक विशिष्ट मानचित्रण, वैश्विक ढेर

से अलग है

गुमनाम मैपिंग का नुकसान:
- प्रत्येक मानचित्रण के आकार सिस्टम के पृष्ठ आकार के एक पूर्णांक एकाधिक है, इस प्रकार यह
पता स्थान की बर्बादी का कारण बन सकता - बनाने और लौटने मैपिंग पूर्व से की तुलना में अधिक भूमि के ऊपर उठाना आवंटित ढेर

यदि ऐसे मैपिंग वाले प्रोग्राम में कोई प्रक्रिया होती है, तो बच्चे को मानचित्रण प्राप्त होता है।

#ifdef USE_MAP_ANON 
#define _BSD_SOURCE 
#endif 
#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <sys/wait.h> 
#include <sys/mman.h> 
#include <fcntl.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) 
{ 
    /*Pointer to shared memory region*/  
    int *addr; 

#ifdef USE_MAP_ANON  /*Use MAP_ANONYMOUS*/   
    addr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);  
    if (addr == MAP_FAILED) {  
     fprintf(stderr, "mmap() failed\n");  
     exit(EXIT_FAILURE); 
    }  

#else  /*Map /dev/zero*/  
    int fd;  
    fd = open("/dev/zero", O_RDWR);  
    if (fd == -1) {  
     fprintf(stderr, "open() failed\n"); 
     exit(EXIT_FAILURE); 
    }  

    addr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);  
    if (addr == MAP_FAILED) {  
     fprintf(stderr, "mmap() failed\n");  
     exit(EXIT_FAILURE);  
    }  

    if (close(fd) == -1) {   /*No longer needed*/  
     fprintf(stderr, "close() failed\n");  
     exit(EXIT_FAILURE);  
    } 
#endif  
    *addr = 1;  /*Initialize integer in mapped region*/  

    switch(fork()) {  /*Parent and child share mapping*/  
    case -1:  
     fprintf(stderr, "fork() failed\n"); 
     exit(EXIT_FAILURE);  

    case 0:   /*Child: increment shared integer and exit*/  
     printf("Child started, value = %d\n", *addr);  
     (*addr)++;  

     if (munmap(addr, sizeof(int)) == -1) {  
      fprintf(stderr, "munmap()() failed\n");  
      exit(EXIT_FAILURE);  
     }  
     exit(EXIT_SUCCESS);  

    default:  /*Parent: wait for child to terminate*/  
     if (wait(NULL) == -1) {  
      fprintf(stderr, "wait() failed\n");  
      exit(EXIT_FAILURE);  
     }  

     printf("In parent, value = %d\n", *addr);   
     if (munmap(addr, sizeof(int)) == -1) {  
      fprintf(stderr, "munmap()() failed\n");  
      exit(EXIT_FAILURE);  
     }   
     exit(EXIT_SUCCESS); 
} 

सूत्रों का कहना है:
लिनक्स प्रोग्रामिंग इंटरफ़ेस
अध्याय 49: स्मृति मैपिंग,
लेखक: माइकल केररिस्क

लिनक्स सिस्टम प्रोग्रामिंग (3 संस्करण निम्नलिखित कार्यक्रम इस थोड़े विरासत को दर्शाता है)
अध्याय 8: मेमोरी प्रबंधन,
लेखक: रॉबर्ट लव

+1

hi @nachiketkulk, क्या MAP_ANONYMOUS का अर्थ वर्चुअल वर्चुअल मेमोरी है? – ransh

संबंधित मुद्दे