В чем разница между MAP_SHARED и MAP_PRIVATE в функции mmap? - PullRequest
13 голосов
/ 01 марта 2012

Играю с 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 ..)

Это работает, как и ожидалось.Но прежде чем я дошел до этого, я попытался ...

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

... и mmap выдал ошибку:

mmap: Permission denied

В общем, в чем разница между двумя флагами (справочная страница не щедра на эту тему)?Какого рода разрешение (и где) я пропускаю?

РЕДАКТИРОВАТЬ

Как это обычно бывает .. частично понял.

Оказываетсяopen нужен флаг O_RDWR.

Итак, правильно ли я считать, что:

  • MAP_PRIVATE - изменения вносятся только в память, а не сохраняются на диск?*
  • MAP_SHARED - изменения будут сохранены на диск ...

... но я нигде ничего не сохраняю, подумал я?Просто работает с памятью.

Ответы [ 2 ]

14 голосов
/ 01 марта 2012

Вы открыли файл в режиме только для чтения. Затем вы попытались отобразить его часть в режиме чтения / записи с установленным параметром MAP_SHARED. В этом контексте MAP_SHARED подразумевает, что если вы пишете в область mmap, ваши изменения будут зафиксированы обратно в самом отображенном файле. Вы не можете сделать это, потому что вы открыли файл в режиме только для чтения.

MAP_PRIVATE работает, потому что записи в область mmap не возвращаются в исходный файл. Когда вы пишете в регион, страницы, в которые они были записаны, копируются в другой регион памяти, возможно, подкрепленный пространством подкачки.

8 голосов
/ 01 марта 2012

Записи в сегмент MAP_SHARED передаются в базовый файл.Вы открыли файл с помощью O_RDONLY, который конфликтует с флагом PROT_WRITE, что препятствует возможности MAP_SHARED выполнять обратную запись в файл.

MAP_PRIVATE не переносит записи обратно в базовый файл, поэтому факт открытияфайл O_RDONLY не является проблемой.

...