mmap函数中MAP_SHARED和MAP_PRIVATE有什么区别?

时间:2012-03-01 16:07:54

标签: c linux mmap

为了它的乐趣,可以使用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 个答案:

答案 0 :(得分:14)

您以只读模式打开文件。然后,您试图在设置了MAP_SHARED的情况下以读/写模式对其中的一部分进行映射。在此上下文中,MAP_SHARED意味着如果您写入mmap&f; d区域,您的更改将提交回映射文件本身。您无法执行此操作,因为您以只读模式打开了文件。

MAP_PRIVATE有效,因为对mmap&f; d区域的写入未提交回原始文件。当您写入区域时,写入的页面将复制到不同的内存区域,可能由交换空间支持。

答案 1 :(得分:8)

写入MAP_SHARED段将被传递到基础文件。您使用O_RDONLY打开了文件,该文件与PROT_WRITE标志冲突,从而阻止MAP_SHARED能够写回文件。

MAP_PRIVATE不会将写入带回基础文件,因此您打开文件O_RDONLY的事实不是问题。