第81章 fork() でプライベートアノニマスマッピングをチェック

 プライベートアノニマスマッピングは MAP_PRIVATE と MAP_ANONYMOUS を組み合わせたマッピングです。

 これもファイルマッピング同様に fork() をした場合は Copy-on-Write が適用されます。

main.c. 

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <sys/mman.h>
  5 #include <sys/stat.h>
  6 #include <sys/types.h>
  7 #include <unistd.h>
  8 #include <fcntl.h>
  9
 10 #define BUF_SIZE 8
 11
 12 int main()
 13 {
 14   int i;
 15   char *mm;
 16
 17   mm = mmap(NULL,BUF_SIZE,PROT_WRITE|PROT_READ,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
 18   if(mm == MAP_FAILED){
 19     perror("mmap");
 20     exit(1);
 21   }
 22
 23   pid_t id = fork();
 24
 25   if(id == 0) {
 26     for(i = 0; i < BUF_SIZE-1; i++)
 27       mm[i] = 'a'+i;
 28     mm[BUF_SIZE-1] = '\0';
 29
 30   } else {
 31     for(i = 0; i < BUF_SIZE-1; i++)
 32       mm[i] = 'a';
 33     mm[BUF_SIZE-1] = '\0';
 34   }
 35
 36   for(i = 0; i < 10; i++)
 37     printf("mm[%d] => %c\n",i,mm[i]);
 38
 39   if(munmap(mm,BUF_SIZE)==-1){
 40     perror("munmap");
 41     exit(1);
 42   }
 43
 44   return 0;
 45 }

ビルドと実行結果. 

$ gcc main.c
$ ./a.out
mm[0] => a
mm[1] => a
mm[2] => a
mm[3] => a
mm[4] => a
mm[5] => a
mm[6] => a
mm[7] =>
mm[8] =>
mm[9] =>
mm[0] => a
mm[1] => b
mm[2] => c
mm[3] => d
mm[4] => e
mm[5] => f
mm[6] => g
mm[7] =>
mm[8] =>
mm[9] =>

 MAP_ANONYMOUS ではメモリー間のマッピングなのでファイルは使われません。

 基本的な挙動は MAP_PRIVATE のファイルマッピングと同じですね。

 17   mm = mmap(NULL,BUF_SIZE,PROT_WRITE|PROT_READ,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
 18   if(mm == MAP_FAILED){
 19     perror("mmap");
 20     exit(1);
 21   }

 この MAP_ANONYMOUS がアノニマスマッピングを指定しています。

 それと fd は -1 を指定します。

 fd 引数は通常は無視されるそうですが、一部のプラットフォームは -1 を指定するように作られているらしいので、MAP_ANONYMOUS を指定するときには fd 引数は -1 に設定しておくようにしてくださいね。

Copyright 2018-2019, by Masaki Komatsu