Bài toán: Chia sẻ thông tin giữa các tiến trình (IPC)
rong các dự án thực tế, yêu cầu chia sẻ thông tin (Inter-Process Communication – IPC) giữa hai hoặc nhiều tiến trình là rất phổ biến. Phương pháp đơn giản nhất là thông qua file, tuy nhiên, tốc độ truy cập file thường chậm. Do đó, giải pháp chia sẻ thông tin trực tiếp qua bộ nhớ thường được ưu tiên để đạt hiệu suất cao hơn.
Một phương pháp tiếp cận (sai lầm) từng được thử nghiệm để chia sẻ bộ nhớ có thể được mô tả như sau:
- Trong Tiến trình A: Cấp phát (
malloc) một con trỏP. - In địa chỉ mà con trỏ
Pđang trỏ tới (giá trị củaP) ra một file trên ổ cứng. - Trong Tiến trình B: Đọc file đó để lấy giá trị địa chỉ.
- Gán giá trị địa chỉ này cho một con trỏ (trong B) và tiến hành đọc/ghi dữ liệu.
Về lý thuyết, cách làm này có vẻ đơn giản. Tuy nhiên, trên thực tế, Tiến trình B sẽ luôn bị crash khi chạy thử (ngay cả khi đã kiểm tra NULL) lúc truy cập vào con trỏ đó.
Nguyên nhân cốt lõi của vấn đề này nằm ở cơ chế Virtual Memory (Bộ nhớ ảo) của hệ điều hành.
Virtual Memory là gì?
Virtual memory có thể được hiểu là cơ chế mà hệ điều hành cung cấp cho mỗi tiến trình một không gian địa chỉ (address space) riêng biệt và độc lập.
Cơ chế này tạo ra một “ảo ảnh” cho tiến trình, khiến nó hoạt động như thể đang sở hữu toàn bộ không gian bộ nhớ và không có sự tồn tại của các tiến trình khác. Trong không gian địa chỉ ảo này, các biến, hàm (function) và lệnh (instruction) được đánh địa chỉ một cách tuần tự và liền kề, thường bắt đầu từ một địa chỉ cố định (phụ thuộc vào từng hệ điều hành).
Hệ quả là, giữa Tiến trình A và Tiến trình B hoàn toàn có thể tồn tại các biến có cùng một địa chỉ ảo. Khi A và B tham chiếu đến biến đó, chúng đều đang tham chiếu thông qua địa chỉ ảo (virtual address) này.

Cơ chế hoạt động: Bảng phân trang và MMU
Để quản lý việc này, hệ điều hành đính kèm với mỗi tiến trình một cấu trúc dữ liệu gọi là bảng phân trang (page table). Bảng này duy trì sự ánh xạ giữa địa chỉ ảo và địa chỉ vật lý (có thể hiểu đơn giản gồm hai cột: virtual address và physical address).
Mỗi khi tiến trình tham chiếu đến một địa chỉ bất kỳ, bộ MMU (Memory Management Unit) – một thành phần phần cứng – sẽ tự động tra cứu trong bảng phân trang của tiến trình đó để tìm ra địa chỉ vật lý (physical address) tương ứng. Sau khi có được địa chỉ vật lý, MMU trả địa chỉ này cho CPU, và CPU dùng nó để truy xuất dữ liệu thực tế đang được lưu trên RAM.
Kết luận: Vấn đề của việc chia sẻ địa chỉ ảo
Đến đây, vấn đề của phương pháp tiếp cận sai lầm ở trên trở nên rõ ràng:
Cùng một giá trị địa chỉ (ví dụ 0x400500), nhưng trong bảng phân trang của Tiến trình A, nó được ánh xạ đến một vị trí bộ nhớ vật lý cụ thể. Trong khi đó, cũng tại địa chỉ ảo 0x400500 trong bảng phân trang của Tiến trình B, nó lại trỏ đến một vị trí vật lý hoàn toàn khác, hoặc thậm chí là một vùng không hợp lệ (dẫn đến crash).
Nguyên nhân là bởi địa chỉ được chia sẻ giữa hai tiến trình là virtual address (địa chỉ ảo), vốn chỉ có ý nghĩa trong nội bộ không gian của từng tiến trình, chứ không phải là physical address (địa chỉ vật lý).

