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

玩转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 

一般来说,两个标志之间有什么区别(man page在这个问题上是不是很慷慨)? 我错过了什么样的权限(以及哪里)?

编辑

就像它通常发生..部分地想出来。

原来open需要一个O_RDWR标志。

那么,我是否正确地认为:

  • MAP_PRIVATE – 仅在内存中进行更改,而不是保存到磁盘?
  • MAP_SHARED – 更改将保存到磁盘…

…但我没有把任何东西保存到任何地方,我想? 只是在内存上运行。

您以只读模式打开文件。 然后,您尝试使用MAP_SHARED集以读/写模式将其部分映射。 在这种情况下MAP_SHARED意味着,如果你写入mmap'd区域,你的改变将被提交回映射文件本身。 您不能这样做,因为您以只读模式打开文件。

MAP_PRIVATE的作品,因为写入到mmap'd区域没有被提交回原始文件。 写入区域时,写入的页面将被复制到内存的不同区域,可能由交换空间支持。

写入MAP_SHARED段将传送到底层文件。 您用O_RDONLY打开文件,这与PROT_WRITE标志冲突,从而防止MAP_SHARED能够回写到文件。

MAP_PRIVATE不带回写到底层文件,所以打开文件O_RDONLY的事实不是问题。