متى يجب علي استخدام mmap للوصول إلى الملفات؟

StackOverflow https://stackoverflow.com/questions/258091

  •  06-07-2019
  •  | 
  •  

سؤال

توفر بيئات POSIX طريقتين على الأقل للوصول إلى الملفات.هناك مكالمات النظام القياسية open(), read(), write(), والأصدقاء، ولكن هناك أيضًا خيار الاستخدام mmap() لتعيين الملف إلى الذاكرة الظاهرية.

متى يفضل استخدام أحدهما على الآخر؟ما هي المزايا الفردية التي تستحق تضمين واجهتين؟

هل كانت مفيدة؟

المحلول

يعد mmap رائعًا إذا كان لديك عمليات متعددة للوصول إلى البيانات بطريقة القراءة فقط من نفس الملف، وهو أمر شائع في نوع أنظمة الخادم التي أكتبها.يسمح mmap لجميع تلك العمليات بمشاركة نفس صفحات الذاكرة الفعلية، مما يوفر الكثير من الذاكرة.

يسمح mmap أيضًا لنظام التشغيل بتحسين عمليات الترحيل.على سبيل المثال، النظر في برنامجين؛البرنامج A الذي يقرأ ملفًا بحجم 1 ميجابايت في مخزن مؤقت يتم إنشاؤه باستخدام malloc، والبرنامج B الذي يقوم بتعيين الملف بحجم 1 ميجابايت إلى الذاكرة.إذا كان على نظام التشغيل تبديل جزء من ذاكرة A، فيجب عليه كتابة محتويات المخزن المؤقت للتبديل قبل أن يتمكن من إعادة استخدام الذاكرة.في حالة B، يمكن إعادة استخدام أية صفحات غير معدلة تم تعيينها على الفور لأن نظام التشغيل يعرف كيفية استعادتها من الملف الموجود الذي تم تعيينها منه.(يمكن لنظام التشغيل اكتشاف الصفحات غير المعدلة عن طريق وضع علامة مبدئية على الصفحات القابلة للكتابة على أنها للقراءة فقط والتقاط أخطاء Seg، على غرار استراتيجية النسخ عند الكتابة).

يعد mmap مفيدًا أيضًا للاتصال بين العمليات.يمكنك تعيين ملف mmap للقراءة/الكتابة في العمليات التي تحتاج إلى الاتصال ثم استخدام أساسيات المزامنة في منطقة mmap'd (هذا هو الغرض من علامة MAP_HASSEMAPHORE).

أحد الأماكن التي يمكن أن يكون فيها mmap محرجًا هو إذا كنت بحاجة إلى العمل مع ملفات كبيرة جدًا على جهاز 32 بت.وذلك لأنه يتعين على mmap العثور على كتلة متجاورة من العناوين في مساحة عنوان العملية الخاصة بك والتي تكون كبيرة بما يكفي لتناسب النطاق الكامل للملف الذي يتم تعيينه.يمكن أن يصبح هذا مشكلة إذا أصبحت مساحة العنوان الخاصة بك مجزأة، حيث قد يكون لديك 2 غيغابايت من مساحة العنوان خالية، ولكن لا يمكن لأي نطاق فردي منها أن يتناسب مع تعيين ملف بسعة 1 غيغابايت.في هذه الحالة، قد يتعين عليك تعيين الملف في أجزاء أصغر مما تريد لجعله مناسبًا.

هناك حرج آخر محتمل في استخدام mmap كبديل للقراءة/الكتابة وهو أنه يتعين عليك بدء رسم الخرائط على إزاحات حجم الصفحة.إذا كنت تريد فقط الحصول على بعض البيانات عند الإزاحة X، فستحتاج إلى إصلاح هذه الإزاحة بحيث تكون متوافقة مع mmap.

وأخيرا، القراءة / الكتابة هي الطريقة الوحيدة لك يستطيع العمل مع بعض أنواع الملفات.لا يمكن استخدام mmap على أشياء مثل الأنابيب وttys.

نصائح أخرى

وكانت منطقة واحدة حيث وجدت mmap () أن لا يكون ميزة عند قراءة الملفات الصغيرة (تحت 16K). كان فوق الصفحة التصدع لقراءة الملف بأكمله عالية جدا بالمقارنة مع مجرد القيام استدعاء نظام قراءة واحدة (). وذلك لأن نواة يمكن satisify أحيانا قراءة تماما في شريحة وقتك، وهذا يعني الشفرة لا تبديل بعيدا. مع خطأ صفحة، ويبدو من المرجح أن برنامج آخر أن من المقرر، مما يجعل عملية الملف لديها الكمون العالي.

وmmap لديه ميزة عندما يكون لديك الوصول العشوائي على الملفات الكبيرة. وهناك ميزة أخرى هي أنه يمكنك الوصول إليه مع عمليات الذاكرة (memcpy، مؤشر الحساب)، دون أن يكلف نفسه عناء مع التخزين المؤقت. عادي I / O يمكن في بعض الأحيان يكون من الصعب للغاية عند استخدام مخازن عندما يكون لديك هياكل أكبر من المخزن الخاص بك. رمز للتعامل مع هذا غالبا ما يكون من الصعب الحصول على حق، mmap هو أسهل عموما. وقال هذا، هناك بعض الفخاخ عند العمل مع mmap. كما الناس التي سبق ذكرها، mmap غير مكلفة جدا لاقامة، لذا فإن الأمر يستحق فقط باستخدام لحجم معين (متفاوتة من آلة إلى آلة).

لمتسلسلة النقي بالوصول إلى الملف، كما أنه ليس دائما الحل الأفضل، على الرغم من مكالمة المناسبة لmadvise يمكن أن تخفف من المشكلة.

وعليك أن تكون حذرا مع قيود المواءمة بين الهندسة المعمارية الخاص بك (SPARC، إيتانيوم)، مع قراءة / كتابة IO غالبا ما يتم محاذاة المخازن المؤقتة بشكل صحيح ولا اعتراض عندما dereferencing مؤشر مسبوكة.

لديك أيضا أن يكون حذرا أن لا الوصول خارج الخريطة. ويمكن أن يحدث بسهولة إذا كنت تستخدم وظائف سلسلة على الخريطة، ولا تحتوي على ملف الخاص بك \ 0 في نهاية المطاف. وسوف يعمل معظم الوقت عند حجم الملف الخاص بك ليست من مضاعفات حجم الصفحة كما شغل في الصفحة الأخيرة مع 0 (المنطقة المعينة دائما في حجم مضاعف من حجم الصفحة الخاصة بك).

بالإضافة إلى إجابات لطيفة أخرى، اقتباس من برمجة نظام لينكس بقلم خبير جوجل روبرت لوف:

مزايا mmap( )

التعامل مع الملفات عن طريق mmap( ) لديه حفنة من المزايا على المعيار read( ) و write( ) مكالمات النظام.من بين هؤلاء:

  • القراءة من والكتابة إلى ملف تم تصنيف الذاكرة تتجنب النسخة الخارجية التي تحدث عند استخدام read( ) أو write( ) مكالمات النظام ، حيث يجب نسخ البيانات من وإلى المخزن المؤقت للمساحة المستخدم.

  • بصرف النظر عن أي أخطاء في الصفحات المحتملة ، فإن القراءة والكتابة إلى ملف تم تصنيفه للذاكرة لا تتحمل أي مكالمة أو مفتاح سياق النظام.الأمر بسيط مثل الوصول إلى الذاكرة.

  • عندما تقوم عمليات متعددة بتعيين نفس الكائن في الذاكرة، تتم مشاركة البيانات بين جميع العمليات.تتم مشاركة التعيينات القابلة للكتابة للقراءة فقط والمشتركة بالكامل ؛تحتوي التعيينات الخاصة القابلة للكتابة على صفحاتها التي لا تقل عن قاع (نسخ على وصول).

  • يتضمن البحث عن الخرائط تلاعبًا بسيطًا بالمؤشر.ليست هناك حاجة ل lseek( ) مكالمة النظام.

لهذه الأسباب، mmap( ) هو الاختيار الذكي للعديد من التطبيقات.

عيوب mmap( )

هناك بعض النقاط التي يجب وضعها في الاعتبار عند الاستخدام mmap( ):

  • تكون تعيينات الذاكرة دائمًا عددًا صحيحًا من الصفحات في الحجم.وبالتالي ، فإن الفرق بين حجم ملف الدعم وعدد عدد صحيح من الصفحات "يضيع" كمساحة الركود.بالنسبة للملفات الصغيرة ، قد تضيع نسبة مئوية كبيرة من التعيين.على سبيل المثال ، مع 4 كيلو بايت صفحات ، فإن رسم خرائط 7 بايت يضيع 4،089 بايت.

  • يجب أن تتناسب تعيينات الذاكرة مع مساحة عنوان العملية.مع مساحة عنوان 32 بت ، يمكن أن يؤدي عدد كبير جدًا من التعيينات المختلفة إلى تجزئة مساحة العنوان ، مما يجعل من الصعب العثور على مناطق مجاورة حرة كبيرة.هذه المشكلة ، بالطبع ، أقل وضوحًا مع مساحة عنوان 64 بت.

  • هناك نفقات إضافية في إنشاء وصيانة تعيينات الذاكرة وهياكل البيانات المرتبطة بها داخل النواة.يتم تجنب هذا النفقات العامة عمومًا عن طريق التخلص من النسخة المزدوجة المذكورة في القسم السابق ، وخاصة بالنسبة للملفات الأكبر والمتكررة التي يتم الوصول إليها بشكل متكرر.

لهذه الأسباب فوائد mmap( ) يتم تحقيقها بشكل كبير عندما يكون الملف المعين كبيرًا (وبالتالي أي مساحة ضائعة هي نسبة مئوية صغيرة من إجمالي التعيين) ، أو عندما يكون الحجم الإجمالي للملف المعين قابلاً للقسمة على حجم الصفحة (وبالتالي لا يوجد مساحة ضائعة ).

ورسم الخرائط الذاكرة لديه القدرة على ميزة سرعة كبيرة مقارنة IO التقليدي. وهو يتيح نظام التشغيل قراءة البيانات من الملف المصدر كما لمست الصفحات في ملف تعيين الذاكرة. هذا يعمل عن طريق إنشاء صفحات يخطأ، والذي يكشف OS ثم OS بتحميل البيانات المناظرة من الملف تلقائيا.

وهذا يعمل بنفس طريقة آلية الترحيل وعادة هو الأمثل لسرعة عالية I / O عن طريق قراءة البيانات الموجودة على حدود الصفحة النظام والأحجام (عادة 4K) - حجم والتي هي الأمثل معظم مخابئ نظام الملفات ل

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top