Các tệp được ánh xạ trong bộ nhớ có thể được sử dụng để thay thế quyền truy cập đọc / ghi hoặc để hỗ trợ chia sẻ đồng thời. Khi bạn sử dụng chúng cho một cơ chế, bạn cũng nhận được cơ chế kia.
Thay vì tìm kiếm và ghi và đọc xung quanh một tệp, bạn ánh xạ nó vào bộ nhớ và chỉ cần truy cập các bit ở nơi bạn mong đợi.
Điều này có thể rất tiện dụng và tùy thuộc vào giao diện bộ nhớ ảo có thể cải thiện hiệu suất. Việc cải thiện hiệu suất có thể xảy ra vì hệ điều hành hiện có thể quản lý "tệp I / O" trước đây cùng với tất cả quyền truy cập bộ nhớ có lập trình khác của bạn và (về lý thuyết) có thể tận dụng các thuật toán phân trang, v.v. mà nó đã được sử dụng để hỗ trợ bộ nhớ ảo cho phần còn lại của chương trình của bạn. Tuy nhiên, nó phụ thuộc vào chất lượng của hệ thống bộ nhớ ảo bên dưới của bạn. Những giai thoại tôi đã nghe nói rằng hệ thống bộ nhớ ảo Solaris và * BSD có thể cải thiện hiệu suất tốt hơn hệ thống VM của Linux - nhưng tôi không có dữ liệu thực nghiệm để sao lưu điều này. YMMV.
Đồng thời xuất hiện khi bạn xem xét khả năng có nhiều quy trình sử dụng cùng một "tệp" thông qua bộ nhớ được ánh xạ. Trong mô hình đọc / ghi, nếu hai quá trình được ghi vào cùng một vùng của tệp, bạn có thể khá yên tâm rằng một trong các dữ liệu của quá trình sẽ đến tệp, ghi đè lên dữ liệu của quá trình kia. Bạn sẽ nhận được cái này hoặc cái kia - nhưng không phải là một số xen kẽ kỳ lạ. Tôi phải thừa nhận rằng tôi không chắc liệu đây có phải là hành vi được yêu cầu bởi bất kỳ tiêu chuẩn nào hay không, nhưng đó là điều bạn có thể dựa vào khá nhiều. (Đây thực sự là câu hỏi tiếp theo rất hay!)
Ngược lại, trong thế giới được ánh xạ, hãy tưởng tượng hai quá trình đều "viết". Họ làm như vậy bằng cách thực hiện "lưu trữ bộ nhớ", dẫn đến cuối cùng là O / S phân trang dữ liệu ra đĩa. Nhưng trong thời gian chờ đợi, việc ghi chồng chéo có thể xảy ra.
Đây là một ví dụ. Giả sử tôi có hai quy trình đều ghi 8 byte ở khoảng cách 1024. Quy trình 1 đang viết '11111111' và quy trình 2 đang viết '22222222'. Nếu họ sử dụng tệp I / O, thì bạn có thể tưởng tượng, sâu trong O / S, có một bộ đệm đầy 1s và một bộ đệm đầy 2s, cả hai đều hướng đến cùng một vị trí trên đĩa. Một trong số họ sẽ đến đích đầu tiên, và người còn lại trong giây. Trong trường hợp này, người thứ hai thắng. Tuy nhiên , nếu tôi đang sử dụng phương pháp tiếp cận tệp ánh xạ bộ nhớ, quy trình 1 sẽ chuyển đến một bộ nhớ lưu trữ 4 byte, tiếp theo là một bộ nhớ lưu trữ 4 byte khác (giả sử đó không phải là kích thước lưu trữ bộ nhớ tối đa). Quy trình 2 sẽ làm điều tương tự. Dựa trên thời điểm các quy trình chạy, bạn có thể thấy bất kỳ thông tin nào sau đây:
11111111
22222222
11112222
22221111
Giải pháp cho điều này là sử dụng loại trừ lẫn nhau rõ ràng - có lẽ là một ý tưởng hay trong mọi trường hợp. Dù sao thì bạn cũng dựa vào O / S để làm "điều đúng đắn" trong trường hợp đọc / ghi tệp I / O.
Nguyên thủy loại trừ lẫn nhau phân loại là mutex. Đối với các tệp được ánh xạ bộ nhớ, tôi khuyên bạn nên xem một mutex được ánh xạ bộ nhớ, có sẵn bằng cách sử dụng (ví dụ) pthread_mutex_init ().
Chỉnh sửa bằng một gotcha: Khi bạn đang sử dụng các tệp được ánh xạ, có một sự cám dỗ để nhúng con trỏ đến dữ liệu trong tệp, trong chính tệp đó (hãy nghĩ đến danh sách được liên kết được lưu trữ trong tệp được ánh xạ). Bạn không muốn làm điều đó, vì tệp có thể được ánh xạ tại các địa chỉ tuyệt đối khác nhau vào các thời điểm khác nhau hoặc trong các quy trình khác nhau. Thay vào đó, hãy sử dụng các hiệu số trong tệp được ánh xạ.