Logo

معمل نظام التشغيل - الأسبوع 6

4 دقائق قراءة
شرائح الدرس
1 / 11

معمل نظم التشغيل - الأسبوع السادس

الملفات المُعيَّنة على الذاكرة: مشاركة بيانات الملفات والوصول إليها عشوائيًا عبر الذاكرة

إدارة الـ Processes والملفات المُعيَّنة على الذاكرة (Memory-Mapped Files) في C#


جدول المحتويات

  1. الملفات المُعيَّنة على الذاكرة
  2. أمثلة برمجية

الملفات المُعيَّنة على الذاكرة

ما هي الملفات المُعيَّنة على الذاكرة؟

تُنشئ الملفات المُعيَّنة على الذاكرة (Memory-Mapped Files) تعيينًا (Mapping) مباشرًا بين ملف موجود على القرص ومنطقة في الذاكرة (RAM). يتيح لك هذا:

  • الوصول إلى بيانات الملف كما لو كانت ذاكرة عادية
  • مشاركة البيانات بين عدة processes بكفاءة
  • التعامل مع الملفات الكبيرة عن طريق تحميل الأجزاء المطلوبة فقط
  • تنفيذ عمليات الوصول العشوائي (Random Access) بسرعة

كيف تعمل

sequenceDiagram
    participant App as Application
    participant OS as Operating System
    participant MMF as Memory-Mapped File
    participant Disk as Disk Storage
    
    App->>OS: Request Memory-Mapped File
    OS->>Disk: Map file to memory region
    Disk-->>OS: File mapped
    OS-->>App: Return MMF handle
    
    App->>MMF: Write data to memory
    MMF->>OS: Update memory region
    OS->>Disk: Sync to disk (lazy/on-demand)
    
    App->>MMF: Read data from memory
    MMF-->>App: Return data instantly

المزايا الرئيسية

  1. وصول سريع: الوصول المباشر إلى الذاكرة أسرع بكثير من إدخال/إخراج الملفات (File I/O) التقليدي
  2. وصول عشوائي: الانتقال إلى أي موضع في الملف فوريًا
  3. الاتصال بين الـ Processes (IPC): يمكن لعدة processes مشاركة نفس المنطقة المُعيَّنة على الذاكرة
  4. كفاءة مع الملفات الكبيرة: تحميل الأجزاء التي تحتاجها فقط إلى الذاكرة

معمارية الملفات المُعيَّنة على الذاكرة

graph LR
    subgraph Process1[Process 1]
        A1[Memory View Accessor]
    end
    
    subgraph Process2[Process 2]
        A2[Memory View Accessor]
    end
    
    subgraph OS[Operating System]
        B[Memory-Mapped File Object]
    end
    
    subgraph Storage[Physical Storage]
        C[File on Disk]
    end
    
    A1 <-->|Read/Write| B
    A2 <-->|Read/Write| B
    B <-->|Maps to| C

أمثلة برمجية

المثال 1: ملف مُعيَّن على الذاكرة (MMF.cs)

يوضح هذا المثال كيفية إنشاء ملف مُعيَّن على الذاكرة واستخدامه لكتابة البيانات وقراءتها.

using System.IO.MemoryMappedFiles;
using System.Text;
 
namespace Process_MMF;
 
public class MMF
{
    public static void Main(string[] args)
    {
        // Define the file path and size
        string filePath = "largefile.txt";
        long fileSize = 1024 *  // = 1 KB
                        1024 *  // = 1 MB
                        100;    // = 100 MB
    
        // Create or open the memory-mapped file
        using (
            var mmf = MemoryMappedFile.CreateFromFile(
                filePath, 
                FileMode.OpenOrCreate, 
                null, 
                fileSize
            ))
        {
            // Create a memory-mapped view accessor to read and write data
            using (var accessor = mmf.CreateViewAccessor())
            {
                // Write data to the memory-mapped file
                string dataToWrite = "Hello, Memory-Mapped Files!";
                byte[] dataBytes = Encoding.UTF8.GetBytes(dataToWrite);
                
                // Write starting at byte position 30
                accessor.WriteArray(30, dataBytes, 0, dataBytes.Length);
    
                // Read 2 bytes starting at position 34
                byte[] readData = new byte[2];
                accessor.ReadArray(34, readData, 0, 2);
    
                string readDataString = Encoding.UTF8.GetString(readData);
                Console.WriteLine("Data read from memory-mapped file: " + readDataString);
 
                Console.ReadKey();
            }
        }
    }
}

شرح الكود

حساب حجم الملف:

long fileSize = 1024 * 1024 * 100;  // 100 MB
  • ينشئ ملفًا بحجم 100 ميجابايت
  • 1024 بايت = 1 كيلوبايت
  • 1024 كيلوبايت = 1 ميجابايت
  • الإجمالي 100 ميجابايت

إنشاء الملف المُعيَّن على الذاكرة:

var mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null, fileSize)
  • filePath: اسم الملف المراد تعيينه
  • FileMode.OpenOrCreate: ينشئ الملف إن لم يكن موجودًا، ويفتحه إن كان موجودًا
  • null: اسم التعيين الافتراضي (تعيين بلا اسم)
  • fileSize: حجم المنطقة المُعيَّنة على الذاكرة

View Accessor:

var accessor = mmf.CreateViewAccessor()
  • ينشئ مُتحكِّم وصول (Accessor) للقراءة من الذاكرة المُعيَّنة والكتابة إليها
  • يوفر وصولًا عشوائيًا لأي موضع بايت

كتابة البيانات:

accessor.WriteArray(30, dataBytes, 0, dataBytes.Length);
  • يكتب البيانات بدءًا من الموضع رقم 30 في الملف
  • المُعطَيات: (الموضع، البيانات، الإزاحة، العدد)

قراءة البيانات:

accessor.ReadArray(34, readData, 0, 2);
  • يقرأ بايتين بدءًا من الموضع رقم 34
  • الموضع 34 سيقرأ "o," من كلمة "Hello" (H=30، e=31، l=32، l=33، o=34)

تصور توضيحي لتخطيط الذاكرة

graph LR
    subgraph MemoryMappedFile[Memory-Mapped File - largefile.txt]
        A[Position 0-29: Empty] --> B[Position 30: 'H']
        B --> C[Position 31: 'e']
        C --> D[Position 32: 'l']
        D --> E[Position 33: 'l']
        E --> F[Position 34: 'o']
        F --> G[Position 35: ',']
        G --> H[Position 36-56: Rest of string]
        H --> I[Position 57-end: Empty]
    end
    
    style F fill:#ffcccc
    style G fill:#ffcccc

ملخص

غطَّى هذا المعمل:

  1. الملفات المُعيَّنة على الذاكرة: الوصول الفعّال إلى الملفات والاتصال بين الـ processes عبر تعيين الذاكرة

أهم النقاط

  • توفر الملفات المُعيَّنة على الذاكرة وصولًا سريعًا وعشوائيًا إلى الملفات الكبيرة
  • التوافق عبر المنصات يتطلب معالجة خاصة بكل نظام تشغيل عند تنفيذ الـ processes
  • يعمل صنف MemoryMappedFile في .NET بسلاسة عبر جميع المنصات

تمارين تطبيقية

  1. عدِّل كود MMF للكتابة والقراءة في مواضع مختلفة
  2. أنشئ برنامجين منفصلين يتواصلان عبر ملف مُعيَّن على الذاكرة مشترك
  3. نفِّذ مُشغِّل processes يعمل عبر منصات متعددة ويكتشف نظام التشغيل تلقائيًا
  4. جرِّب أحجام ملفات مختلفة وقِس الفروق في الأداء

مصادر إضافية