Các tệp ánh xạ 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 có được cơ chế khác.
Thay vì lseeking và viết và đọc xung quanh trong một tập tin, bạn ánh xạ nó vào bộ nhớ và chỉ cần truy cập vào các bit mà 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. Cải thiện hiệu suất có thể xảy ra vì hệ điều hành giờ đây có thể quản lý "tệp I/O" cũ này cùng với tất cả truy cập bộ nhớ có lập trình khác của bạn và có thể (theo lý thuyết) tận dụng các thuật toán phân trang và do đó nó đã được sử dụng để hỗ trợ bộ nhớ ảo cho số 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 cơ bản của bạn. Giai thoại tôi đã nghe nói rằng các hệ thống bộ nhớ ảo Solaris và * BSD có thể cho thấy cải tiến hiệu suất tốt hơn so với hệ thống máy ảo 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 đi vào hình ảnh khi bạn xem xét khả năng của 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 tiến trình ghi vào cùng một vùng của tệp, bạn có thể yên tâm rằng một trong các dữ liệu của quy trình sẽ đến trong tệp, ghi đè lên dữ liệu của quy trình khác. Bạn sẽ nhận được một, hoặc khác - nhưng không phải một số intermingling 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 bắt buộc bởi bất kỳ tiêu chuẩn nào hay không, nhưng đó là điều mà bạn có thể dựa vào khá nhiều. (Đó thực sự là câu hỏi tiếp theo về nông nghiệp!)
Trong thế giới được ánh xạ, ngược lại, hãy tưởng tượng hai quy trình vừa là "viết". Họ làm như vậy bằng cách làm "bộ nhớ cửa hàng", mà kết quả trong O/S phân trang dữ liệu ra đĩa - cuối cùng. Nhưng trong khi chờ đợi, việc viết chồng chéo có thể được dự kiến sẽ xảy ra.
Đây là một ví dụ. Nói rằng tôi có hai quá trình cả hai bằng văn bản 8 byte tại offset 1024. Quy trình 1 là viết '11111111' và quá trình 2 đang viết '22222222'. Nếu họ sử dụng tập tin 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 đó trước, và một giây nữa. Trong trường hợp này, cái thứ hai sẽ 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 một kho lưu trữ bộ nhớ 4 byte, tiếp theo là một kho lưu trữ bộ nhớ khác là 4 byte (giả sử không phải kích thước 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 quy trình chạy, bạn có thể thấy bất kỳ điều nào sau đây:
11111111
22222222
11112222
22221111
Giải pháp này là sử dụng loại trừ lẫn nhau rõ ràng - có lẽ là ý tưởng hay trong mọi trường hợp. Bạn đã được loại dựa vào O/S để làm "điều đúng" trong trường hợp đọc/ghi tập tin I/O, anyway.
Nguyên tắc loại trừ lẫn nhau loại trừ là mutex. Đối với các tệp được ánh xạ bộ nhớ, tôi khuyên bạn nên xem xét 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 lần xác thực: Khi bạn đang sử dụng các tệp được ánh xạ, có sự cám dỗ để nhúng con trỏ vào dữ liệu trong tệp, trong chính tệp đó (nghĩ 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 bù trừ trong tệp được ánh xạ.
Trên Windows ít nhất bạn có thể bản đồ nhiều 32bit lượt xem của một tệp mmap lớn hơn - có thể hiệu quả hơn là cố gắng xử lý các tệp rất lớn bằng hàm CRT thông thường –
@MarkR Bạn đã viết "sao chép thêm của mình không chỉ mất thời gian , nhưng ** giảm hiệu quả của bộ nhớ cache của CPU bằng cách truy cập vào bản sao dữ liệu bổ sung này. ** ". (** nhấn mạnh ** của tôi). Bạn có thể giải thích cách bản sao đệm bổ sung trong hạt nhân cản trở hiệu quả của bộ nhớ cache của CPU không? – Geek
@Geek truy cập gấp đôi bộ nhớ nhiều gấp đôi bộ nhớ cache bị lãng phí (rất gần). – immibis