2016-11-03 16 views
5

मेरे पास दो अलग-अलग अनुप्रयोगों के बीच POSIX मॉडल के भीतर एक साझा गतिशील सरणी है। मैं प्रतिलिपि के बिना अपना आकार बदलने की क्षमता रखना चाहता हूं। दुर्भाग्य से मुझे सी भाषा में POSIX साझा स्मृति को बढ़ाने और घटाने का सही समाधान नहीं मिला। वेब में मुझे खराब स्पष्टीकरण और कुटिल उदाहरणों के साथ कई दस्तावेज मिले हैं। मैं कुछ रोचक विषयों को खोजने के लिए प्रबंधित किया है, लेकिन उन सभी को मेरे लिए अनुपयुक्त हैं:POSIX साझा स्मृति का आकार बदलें। एक कामकाजी उदाहरण

  1. "Linux System Programming" - "Mapping Files into Memory" Part: "Resizing a Mapping" - जहां SHM आकार बदलने के लिए कोई काम कर उदाहरण है।

  2. How do I implement dynamic shared memory resizing? - केवल एक विवरण। कोई उदाहरण नहीं है।

  3. mremap function failed to allocate new memory - पसंदीदा उत्तर गलत काम करता है।

  4. Fast resize of a mmap file

  5. Characteristics of mremap function in Linux

  6. mremap function failed to allocate new memory

  7. c/linux - ftruncate and POSIX Shared Memory Segments - rszshm बिल्कुल mremap() का उपयोग नहीं करता। यह इसके बजाय स्मृति की प्रतिलिपि बनाएँ। सबसे बुरा तरीका।

मैंने एक उदाहरण विकसित किया है क्योंकि मैं प्रलेखन को समझता हूं। दुर्भाग्य से यह सही काम नहीं कर रहा है। कृपया मुझे एक सलाह दें, जहां मैं गलत हूं। और कृपया मुझे एक कामकाजी उदाहरण देने के लिए बहुत दयालु रहें।

प्रलेखन में मैंने पाया है कि मुझे mremap() से पहले ftruncate() का उपयोग करना है, लेकिन मुझे उनका उपयोग करने के लिए सही वाक्यविन्यास नहीं मिला। इसके अलावा, mremap() गठबंधन स्मृति पृष्ठों के साथ काम करता है। इस मामले में साझा मेमोरी को सही ढंग से कैसे बढ़ाएं?

/* main.c */ 
#define _GNU_SOURCE 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <fcntl.h> 
#include <sys/shm.h> 
#include <sys/stat.h> 
#include <sys/mman.h> 
#include <sys/types.h> 
#include <errno.h> 

int main(void) 
{ 
    size_t size_of_mem = 1024; 
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, 
         S_IRWXO | S_IRUSR | S_IWUSR); 
    if (fd == -1) 
    { 
     perror("Error in shm_open"); 
     return EXIT_FAILURE; 
    } 

    if (ftruncate(fd, size_of_mem) == -1) 
    { 
     perror("Error in ftruncate"); 
     return EXIT_FAILURE; 
    } 

    void *shm_address = mmap(0, size_of_mem, 
          PROT_READ | PROT_WRITE | PROT_EXEC, 
          MAP_SHARED, fd, 0); 
    if (shm_address == MAP_FAILED) 
    { 
     perror("Error mmapping the file"); 
     return EXIT_FAILURE; 
    } 

    /* Increase shard memory */ 
    for (size_t i=0; i<1024; ++i){ 

     /* Does 8 align memory page? */ 
     size_t new_size_of_mem = 1024+(8*i); 

     if (ftruncate(fd, new_size_of_mem) == -1) 
     { 
      perror("Error in ftruncate"); 
      return EXIT_FAILURE; 
     } 

     /* 
      mremap() works with aligned memory pages. 
      How to properly increase shared memory in this case? 
     */ 
     void *temp = mremap(shm_address, size_of_mem, new_size_of_mem, MREMAP_MAYMOVE); 
     if(temp == (void*)-1) 
     { 
      perror("Error on mremap()"); 
      return EXIT_FAILURE; 
     } 

     size_of_mem = new_size_of_mem; 

    } 

    return 0; 
} 

बिल्ड:

$ gcc -g -O0 -ggdb -pipe -Wall -Wextra -Wpedantic -Wshadow -march=native -std=c11 -o ./main ./main.c -lrt 

रन:

$ ./main 
Error on mremap(): Bad address 
+0

कम से कम आप pagesize के मामले में आकार को मापने के लिए होगा। 'getpagesize() 'या' sysconf() 'देखें। और, प्रक्रियाओं के बीच स्मृति साझा करने के लिए आपको अन्य प्रक्रियाओं के लिए नए आकार को संवाद करने का एक तरीका खोजना होगा। – joop

उत्तर

2

आप नए आवंटित/पुनः मानचित्रित temp करने के लिए आवंटित स्मृति का पता खो रहे हैं।

इसका मतलब है कि, लूप के दूसरे चक्र के बाद से, आप पहले से ही चलती मेमोरी को ले जा रहे हैं।

mremap लौटा मूल्य की जांच के बाद आप shm_address सूचक में नए पते को फिर से साइन कर सकते हैं।

void *temp = mremap(shm_address, size_of_mem, new_size_of_mem, MREMAP_MAYMOVE); 
if(temp == (void*)-1) 
{ 
    perror("Error on mremap()"); 
    return EXIT_FAILURE; 
} 

shm_address = temp; 
+0

बहुत बहुत धन्यवाद। अब यह वास्तव में त्रुटियों के बिना काम करता है। प्रश्न के बारे में कैसे। mremap() गठबंधन स्मृति पृष्ठों के साथ काम करता है। इस मामले में साझा मेमोरी को सही ढंग से कैसे बढ़ाएं? –

+1

यह एक बड़ा सवाल है। कुछ linux managemnt गुरु से एक अच्छी व्याख्या करने के लिए एक अलग सवाल पोस्ट करें। मैं यहां क्या कह सकता हूं कि यदि कॉलर द्वारा प्रदान किया गया लेन पैरामीटर पृष्ठ सीमा पर गठबंधन नहीं किया गया है तो मानचित्रण अगले पूर्ण पृष्ठ तक गोल हो जाएगा।इस अतिरिक्त मेमोरी के अंदर बाइट्स, अंतिम वैध बाइट और मैपिंग के अंत के बीच, शून्य-भरे हुए हैं। उस क्षेत्र से कोई भी पढ़ा शून्य लौटाएगा। – LPs

+0

फिर से धन्यवाद। बहुत उपयोगी! –

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