سؤال

عندما نقوم بتخطيط ملف للذاكرة ، يلزم مكالمة النظام. هل تتطلب الوصول اللاحق إلى الملف مكالمات النظام أم أن صفحة الذاكرة الافتراضية للعملية المعينة إلى ذاكرة التخزين المؤقت للصفحة الفعلية في الذاكرة؟

تحديث: ما أريد معرفته أيضًا هو أنه إذا كانت عمليات متعددة تصل إلى نفس الملف من خلال MMAP. سوف يصلون إلى نفس جزء الذاكرة الفعلية.

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

المحلول

لا حاجة لمكالمات نظام إضافية (من خلال عمليتك), ، يمكنك الوصول إليها فقط مثل الذاكرة العادية. عندما تنتهي من الملف ، فقط اتصل munmap.

قيمة الإرجاع

على النجاح ، mmap()يعيد مؤشر إلى المنطقة المعينة. عند الخطأ ، القيمة MAP_FAILED (أي ، (void *) -1) يتم إرجاعه ، ويتم تعيين errno بشكل مناسب. على النجاح ، munmap() إرجاع 0 ، عند الفشل -1 ، و errno تم تعيينه (ربما ل EINVAL).

انظر صفحة الرجل هنا للحصول على التفاصيل.

تحرير للتوضيح:

أنا أقول أن الوظيفة تقوم بتعيين الملف في مساحة ذاكرة عملية الاتصال وتُرجع مؤشرًا إلى بداية كتلة الذاكرة.

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

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

نصائح أخرى

عندما تقوم بـ MMAP ملف ، يقوم Linux بإنشاء إدخالات في وحدة إدارة الذاكرة). يراقب MMU على جميع القراءات وتكتب وحدة المعالجة المركزية إلى ذاكرة الوصول العشوائي الحقيقية. وبهذه الطريقة ، تعرف عند الوصول إلى أجزاء من الذاكرة mmap() عاد. إن قراءة الأجزاء التي لم تتم بعد في ذاكرة الوصول العشوائي الحقيقية ستؤدي إلى أخطاء في الصفحات. ستقوم MMU بالقبض عليهم ويدعو روتين kernel لتحميل الجزء الأيمن من الملف في ذاكرة الوصول العشوائي في مكان ما ، ثم سيقوم بتحديث الإدخال في جدول MMU بحيث يبدو أن البيانات موجودة الآن على العنوان mmap() أعطاك. في الواقع ، سيكون في مكان آخر ولكن MMU ستجعل هذا شفافًا تمامًا.

عندما تكتب إلى الذاكرة ، ستقوم MMU بمناسبة الصفحات المعدلة على أنها "قذرة". عندما يتم مسحهم (لأنك تصل إلى المزيد من الملف أو لأنك تتصل munmap()) ، ثم سيتم كتابة التغييرات على القرص.

لذلك في كل مرة يحدث فيها خطأ في الصفحة وتدفق الصفحة القذرة ، تحدث مكالمة النظام. ولكن نظرًا لأن الصفحات 4 أو 8 كيلو بايت ، فنادراً ما تحدث. أيضًا ، سيتم تحميل kernel أكثر من صفحة واحدة في وقت واحد ، وبالتالي يتم تقليل عدد مكالمات النظام مرة أخرى. أخيرًا ، يتم استخدام نفس الكود لتنفيذ التبديل ، لذلك تم تحسينه للغاية.

كل هذه الآثار تجعل MMAP فعالة للغاية.

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