2012-10-29 16 views
7
  • shm_open()
  • एक पूर्वनिर्धारित बड़ा length
  • fork() (कई बार) के साथ mmap()
  • ftruncate() होगा पर

इस की बात यह सुनिश्चित करें कि fork() द्वारा पैदा की हर प्रक्रिया एक है बनाने के लिए है एक ही पते पर साझा खंड। फिर भी, मैं रैम को हर समय व्यस्त रखना नहीं चाहता, लेकिन गतिशील रूप से इसका आकार बदलता हूं (आकार के साथ 0 - बड़े length)।क्या यह बेन मेमापड के बाद साझा किए गए मेमोरी ऑब्जेक्ट को ftruncate करना सुरक्षित है?

क्या यह काम कर सकता है? क्या यूबी है?

उत्तर

8

नहीं, यह ठीक है। आप किसी भी समय अंतर्निहित फ़ाइल को छोटा कर सकते हैं, लेकिन यदि आप फ़ाइल की सीमाओं से परे स्मृति तक पहुंचते हैं तो आपको SIGBUS प्राप्त हो सकता है। इसलिए, आपको फ़ाइल की वर्तमान लंबाई से परे स्मृति को छूने के लिए बेहद सावधान रहना होगा (या SIGBUS पकड़ें और इससे निपटें)।

man 2 mmap से

:

एक मैप की गई क्षेत्र के

उपयोग इन संकेतों में परिणाम कर सकते हैं:

बफर के एक हिस्से कि उदाहरण के लिए फ़ाइल अनुरूप नहीं है (करने के लिए SIGBUS का प्रयास किया गया उपयोग, परे फ़ाइल का अंत, जिसमें शामिल है, जहां एक और प्रक्रिया ने फ़ाइल को छोटा कर दिया है)।

+0

यही वह है जो मैं मानता हूं, लेकिन क्या 'मुनमप' ट्रिगर गंदे पृष्ठों को लिख सकता है जो 'सिगबुस' को ट्रिगर कर सकता है? –

+0

इसे स्वीकार करने के रूप में चिह्नित करना, क्योंकि यह मेरे प्रश्न का उत्तर देता है। लेकिन डेमन की विधि बेहतर प्रबंधनीय है (मैं 'mmap'ed रेंज के बीच में पृष्ठों को अनलोड कर सकता हूं)। –

+0

@nneonneo मुझे नहीं लगता कि यह काफी सही है। मेरा मानना ​​है कि मैपिंग को अपडेट करने के लिए आपको 'ftruncate' के बाद' mremap' करने की आवश्यकता है। फिर भी आपको 'EremM' के साथ विफल होने 'mremap' को रोकने के लिए मूल रूप से बड़े आकार को आवंटित करना चाहिए। – jleahy

1

इसका आकार बदलें।

मैं राम व्यस्त हर समय

है यही कारण है कि कर्नेल आभासी स्मृति के साथ आप के लिए क्या करेंगे रखने के लिए नहीं करना चाहती। जब तक आप mlock() या MAP_LOCKED का उपयोग नहीं करते हैं, तब तक इसे आवश्यक/उपयुक्त के रूप में पेश किया जाएगा।

+0

अच्छी तरह से, रैम के साथ ही स्वैप। मैं मैप किए गए क्षेत्र के मध्य में कुछ समय (कुछ कर्नेल को इसे करने के लिए मजबूर कर रहा हूं) का उपयोग कर सकता हूं, लेकिन फिर मैं इसे रनटाइम के बाकी हिस्सों के बारे में भूल सकता था। इसलिए मुझे लगता है कि मुझे स्पष्ट रूप से यह बताने का एक तरीका चाहिए कि मैं पता स्थान के उस हिस्से का उपयोग नहीं कर रहा हूं। –

+0

आप 'madvise()' का उपयोग कर सकते हैं, लेकिन ध्यान रखें कि व्यवहार पर कोई गारंटी नहीं है। –

+0

मुझे लगता है कि मैं 'MADV_REMOVE' का उपयोग करूंगा। लेकिन अगर मुझे उस जगह की जरूरत है तो मुझे क्या करना चाहिए? –

1

मैपिंग्स जितनी बड़ी हो उतनी बड़ी बनाएं, जब तक कि आप वास्तव में इसका उपयोग नहीं करते हैं, तब तक यह "व्यस्त व्यस्त रहें" नहीं होगा।

आप रैम व्यस्त के बाद आप इसे का उपयोग किया जाता है रखने के बारे में चिंतित हैं, तो फोन madvise(MADV_DONTNEED) - इस पृष्ठों शुद्ध और यदि आप उन्हें पुन: पहुंच तुम वापस शून्य पूल से नए पृष्ठों दे देंगे।

+0

कोई ऐसा ऑपरेशन नहीं है जिसे मुझे उस श्रेणी में लिखने से पहले करने की ज़रूरत है जिसे 'MADV_DONTNEED' के रूप में चिह्नित किया गया है, है ना? –

+0

ध्यान दें कि शून्य भरने का व्यवहार केवल उन मामलों में है जहां बैकिंग स्टोर में अब उन पृष्ठों को नहीं है (क्योंकि यह उस प्रश्न में हो सकता है जहां कुछ डेटा 'ftruncate' द्वारा छोड़ा जा सकता था)। –

+0

@LorenzoPistone: आपको कुछ भी नहीं करना है, नहीं। 'MADV_DONTNEED' पृष्ठों को छोड़ देगा और या तो (यदि फ़ाइल द्वारा समर्थित है) डिस्क से पृष्ठों को पारदर्शी रूप से आवश्यक रूप से लोड करें, या (एनन मैपिंग) बस आपको एक शून्य पृष्ठ फेंक दें। ध्यान दें कि उत्तरार्द्ध है - कम से कम मेरी राय में - वास्तव में "गलत" व्यवहार, क्योंकि पॉज़िक्स कहता है कि अर्थशास्त्रिक्स _not_ बदल गए हैं (जो काफी मामला है!)। यह वही है जो आप चाहते हैं। – Damon