Operating System Lab - Week 6
4 min read
Lesson slides
1 / 11
Process Management and Memory-Mapped Files in C#
Table of Contents
Memory-Mapped Files
What are Memory-Mapped Files?
Memory-mapped files create a direct mapping between a file on disk and a region in memory (RAM). This allows you to:
- Access file data as if it were regular memory
- Share data between multiple processes efficiently
- Work with large files by loading only needed portions
- Perform random access operations quickly
How It Works
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 instantlyKey Advantages
- Fast Access: Direct memory access is much faster than traditional file I/O
- Random Access: Jump to any position in the file instantly
- Inter-Process Communication: Multiple processes can share the same memory-mapped region
- Efficient for Large Files: Load only the portions you need into memory
Memory-Mapped File Architecture
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| CCode Examples
Example 1: Memory-Mapped File (MMF.cs)
This example demonstrates creating and using a memory-mapped file to write and read data.
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();
}
}
}
}Code Explanation
File Size Calculation:
long fileSize = 1024 * 1024 * 100; // 100 MB- Creates a 100 MB file
- 1024 bytes = 1 KB
- 1024 KB = 1 MB
- 100 MB total
Creating the Memory-Mapped File:
var mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null, fileSize)filePath: Name of the file to mapFileMode.OpenOrCreate: Creates file if it doesn't exist, opens if it doesnull: Default mapping name (unnamed mapping)fileSize: Size of the memory-mapped region
View Accessor:
var accessor = mmf.CreateViewAccessor()- Creates an accessor to read/write to the mapped memory
- Provides random access to any byte position
Writing Data:
accessor.WriteArray(30, dataBytes, 0, dataBytes.Length);- Writes data starting at byte position 30 in the file
- Parameters: (position, data, offset, count)
Reading Data:
accessor.ReadArray(34, readData, 0, 2);- Reads 2 bytes starting at position 34
- Position 34 would read "o," from "Hello" (H=30, e=31, l=32, l=33, o=34)
Memory Layout Visualization
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:#ffccccSummary
This lab covered:
- Memory-Mapped Files: Efficient file access and inter-process communication through memory mapping
Key Takeaways
- Memory-mapped files provide fast, random access to large files
- Cross-platform compatibility requires OS-specific handling for process execution
- The .NET MemoryMappedFile class works seamlessly across platforms
Practice Exercises
- Modify the MMF code to write and read at different positions
- Create two separate programs that communicate through a shared memory-mapped file
- Implement a cross-platform process launcher that detects the OS automatically
- Experiment with different file sizes and measure performance differences