2012-03-01 10 views
12

zabawy z mmap dla zabawy, mam następujący kod:Jaka jest różnica między MAP_SHARED i MAP_PRIVATE w funkcji mmap?

(.. 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 ..) 

to działa zgodnie z oczekiwaniami. Ale zanim dostałem się do tego, próbowałem ...

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

... i mmap błędami się z:

mmap: Permission denied 

W ogóle, jaka jest różnica między tymi dwoma flagami (mężczyzna strona ISN” hojny na ten temat)? Jakiego rodzaju pozwolenie (i gdzie) brakuje mi?

EDIT

Jak to zwykle bywa, .. częściowo zdobione.

Okazało się, że open potrzebna jest flaga O_RDWR.

Więc mam rację przyjąć, że:

  • MAP_PRIVATE - zmiany dokonywane są tylko w pamięci, a nie zapisane na dysku?
  • MAP_SHARED - zmiany zostaną zapisane na dysku ...

... ale ja nie oszczędzając niczego na dysku w dowolnym miejscu, pomyślałem? Po prostu działa na pamięć.

+1

', O_RDONLY);' Plik jest tylko do odczytu. Nie można go używać jako pamięci masowej dla obszaru 'PROT_READ | PROT_WRITE' mmap() ed, ponieważ nie jest on zapisywalny. Mapowanie "MAP_PRIVATE" nie musi zapisywać do pliku (plik jest używany tylko do odczytu, prawdopodobnie przez COW) Uwaga: Nie oczekiwałbym, że rozszerzenie tyldy zadziała dla open (2). Byłbym zdumiony, gdyby to zadziałało. – wildplasser

+0

Otóż, był to tylko szybki sposób, aby zdobyć prawdziwą bazę, nawet o tym nie myśleć. Dzięki, ustalone dla poprawności. – ntl0ve

Odpowiedz

7

Zapis do segmentu MAP_SHARED jest przenoszony do pliku bazowego. Otworzyłeś plik O_RDONLY, który jest w konflikcie z flagą PROT_WRITE, uniemożliwiając w ten sposób MAP_SHARED możliwość zapisu z powrotem do pliku.

MAP_PRIVATE nie przenosi zapisów do pliku bazowego, więc fakt, że otworzyłeś plik O_RDONLY nie jest problemem.

+0

Kiedy moje zmiany w pamięci są uwzględniane na dysku? Czy muszę zadzwonić, czy jest to automatyczne? Jeśli tak, jakiekolwiek buforowanie? – ntl0ve

+0

Krótka odpowiedź: nie wiesz. Cokolwiek od teraz do wieczności. munmap() może przepłukać bufory dyskowe, w zależności od fazy księżyca. – wildplasser

+0

Mam to. Znaleźliśmy również 'msync', który obiecuje wymuszenie spłukiwania/synchronizacji. Dzięki. – ntl0ve

13

Otworzyłeś plik w trybie tylko do odczytu. Następnie próbowałeś zmapować jego część w trybie odczytu/zapisu z zestawem MAP_SHARED. W tym kontekście MAP_SHARED oznacza, że ​​jeśli napiszesz do regionu mmap'd, twoje zmiany zostaną zatwierdzone z powrotem do samego zmapowanego pliku. Nie możesz tego zrobić, ponieważ otworzyłeś plik w trybie tylko do odczytu.

MAP_PRIVATE działa, ponieważ zapisy do regionu mmap'd nie są zatwierdzane z powrotem do oryginalnego pliku. Kiedy piszesz do regionu, strony, które zostały zapisane, są kopiowane do innego regionu pamięci, być może wspierane przez przestrzeń wymiany.

Powiązane problemy