web-dev-qa-db-ja.com

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

一般に、2つのフラグの違いは何ですか(manページはこのテーマについて寛大ではありません)?どのような許可(およびどこ)が欠落していますか?

[〜#〜]編集[〜#〜]

それが通常起こるように..部分的にそれを理解しました。

openにはO_RDWRフラグが必要であることが判明しました。

だから、私はそれを仮定するのは正しいですか?

  • MAP_PRIVATE-変更はメモリのみで行われ、ディスクには保存されませんか?
  • MAP_SHARED-変更はディスクに保存されます...

...しかし、私はどこにもディスクに何も保存していないと思いましたか?メモリを操作するだけです。

13
ntl0ve

ファイルを読み取り専用モードで開きました。次に、MAP_SHAREDを設定して、読み取り/書き込みモードでその一部をmmapしようとしました。このコンテキストでは、MAP_SHAREDは、mmapされた領域に書き込むと、変更がマップされたファイル自体にコミットされることを意味します。ファイルを読み取り専用モードで開いたため、これを行うことはできません。

MAP_PRIVATEが機能するのは、mmapされた領域への書き込みが元のファイルにコミットされないためです。領域に書き込むと、書き込まれたページがメモリの別の領域にコピーされ、スワップスペースによってバックアップされる可能性があります。

14
karunski

MAP_SHAREDセグメントへの書き込みは、基になるファイルに引き継がれます。 O_RDONLYを使用してファイルを開いたため、PROT_WRITEフラグと競合するため、MAP_SHAREDがファイルに書き戻すことができません。

MAP_PRIVATEは基になるファイルへの書き込みを持ち帰らないため、ファイルO_RDONLYを開いたという事実は問題ではありません。

8
Tim