2012-03-01 34 views
12

Chơi xung quanh với mmap cho những niềm vui của nó, tôi có đoạn mã sau:Sự khác nhau giữa MAP_SHARED và MAP_PRIVATE trong hàm mmap là gì?

(.. snip ..) 
fd = open("/home/me/straight_a.txt", O_RDONLY); 
if (fd == -1) { 
    perror("open"); 
    exit(1); 
} 

m = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0); 

if (m == MAP_FAILED) { 
    perror("mmap"); 
    exit(1); 
} 

printf("m is %p\n", m); 

printf("*m = %c\n", *m); 
printf("*(m+1) = %c\n", *(m+1)); 
(.. snip ..) 

này hoạt động như mong đợi. Nhưng trước khi tôi đến đây, tôi đã cố gắng ...

m = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, 0); 

... và mmap errored ra với:

mmap: Permission denied 

Nói chung, sự khác biệt giữa hai cờ là những gì (người đàn ông trang isn' t để hào phóng về chủ đề này)? Tôi đang thiếu loại giấy phép nào (và ở đâu)?

EDIT

Giống như nó thường xảy ra .. một phần figured it out.

Tắt open cần cờ O_RDWR.

Vì vậy, tôi đúng khi cho rằng:

  • MAP_PRIVATE - những thay đổi được thực hiện trong bộ nhớ mà thôi, không được lưu vào đĩa?
  • MAP_SHARED - thay đổi này sẽ được lưu vào đĩa ...

... nhưng tôi không tiết kiệm bất cứ điều gì vào đĩa ở bất cứ đâu, tôi nghĩ? Chỉ hoạt động trên bộ nhớ.

+1

', O_RDONLY);' Tệp là chỉ đọc. Nó không thể được sử dụng như một lưu trữ sao lưu cho vùng 'PROT_READ | PROT_WRITE' mmap() ed bởi vì nó không thể ghi được. Ánh xạ 'MAP_PRIVATE' không cần ghi vào tệp (tệp chỉ được sử dụng để đọc, có lẽ là COW) Lưu ý: Tôi không mong đợi mở rộng dấu ngã để làm việc để mở (2). Nó sẽ làm tôi ngạc nhiên nếu nó hoạt động. – wildplasser

+0

Phải, đó chỉ là một cách nhanh chóng để có được thư mục cơ bản thực sự từ đó, thậm chí không nghĩ về nó. Cảm ơn, cố định vì lợi ích của sự chính xác. – ntl0ve

Trả lời

7

Ghi vào phân đoạn MAP_SHARED được chuyển đến tệp cơ bản. Bạn đã mở tệp bằng O_RDONLY, xung đột với cờ PROT_WRITE, do đó ngăn MAP_SHARED không thể ghi lại tệp.

MAP_PRIVATE không ghi lại tệp cơ bản, vì vậy thực tế là bạn đã mở tệp O_RDONLY không phải là vấn đề.

+0

Khi nào các thay đổi trong bộ nhớ của tôi được ghi vào đĩa? Tôi có cần gọi hay tự động không? Nếu vậy, có bất kỳ bộ đệm nào không? – ntl0ve

+0

Anwer ngắn: bạn không biết. Bất cứ điều gì giữa bây giờ và vĩnh cửu. munmap() có thể xóa các bộ đệm đĩa, tùy thuộc vào giai đoạn của mặt trăng. – wildplasser

+0

OK. Cũng tìm thấy 'msync', hứa hẹn sẽ buộc đồng bộ/tuôn ra. Cảm ơn. – ntl0ve

13

Bạn đã mở tệp ở chế độ chỉ đọc. Sau đó, bạn đã cố gắng để mmap một phần của nó trong chế độ đọc/ghi với MAP_SHARED thiết lập. Trong bối cảnh này MAP_SHARED ngụ ý rằng nếu bạn ghi vào vùng mmap'd, các thay đổi của bạn sẽ được cam kết trở lại chính tệp đã được ánh xạ. Bạn không thể làm điều này vì bạn đã mở tệp ở chế độ chỉ đọc.

Tác phẩm MAP_PRIVATE vì ghi vào vùng mmap'd không được cam kết trở lại tệp gốc. Khi bạn viết vào khu vực, các trang được ghi vào sẽ được sao chép sang một vùng bộ nhớ khác, có thể được hỗ trợ bởi không gian hoán đổi.

Các vấn đề liên quan