通过使用我们发现,使用映射区来完成文件读写操作十分方便,父子进程间通信也较容易。但缺陷是,每次创建映射区一定要依赖一个文件才能实现。通常为了建立映射区要open一个temp文件,创建好了再unlink、close掉,比较麻烦。 可以直接使用匿名映射来代替。其实Linux系统给我们提供了创建匿名映射区的方法,无需依赖一个文件即可创建映射区。同样需要借助标志位参数flags来指定:MAP_ANONYMOUS (或MAP_ANON)。如:int *p = mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
"4"随意举例,该位置表大小,可依实际需要填写。offset仍必须为4k的整数倍。
需注意的是,MAP_ANONYMOUS和MAP_ANON这两个宏是Linux操作系统特有的宏。在其它unix和类Unix操作系统中如无该宏定义,可使用如下两步来完成匿名映射区的建立(Linux也可以):
fd = open("/dev/zero", O_RDWR);
p = mmap(NULL, size, PROT_READ|PROT_WRITE, MMAP_SHARED, fd, 0);
Linux系统中的两个设备文件:/dev/zero,其可以提供无穷无尽的数据,想要多大,就可以多大;/dev/null,为黑洞文件,可以吞掉一切东西,类似回收站,只是不可以回收,彻底删除(可以管道重定向到该文件,清理屏幕)。
[root@localhost mmap]# ls -l /dev/null
crw-rw-rw-. 1 root root 1, 3 Mar 29 23:32 /dev/null
1,3 表示设备文件的:主设备号,从设备号
Unix操作系统发展历史: 丹尼斯里奇是C语言之父
Linux之父是Linus Torvalds 上图中除了unix,其余都是类unix操作系统。
//匿名映射
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>int main(void)
{int *p;pid_t pid;int fd;fd = open("/dev/zero", O_RDWR);p = mmap(NULL, 400, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);if(p == MAP_FAILED){ perror("mmap error");exit(1);}pid = fork(); //创建子进程if(pid == 0){*p = 2000;printf("child, *p = %d\n", *p);} else {sleep(1);printf("parent, *p = %d\n", *p);}munmap(p, 4); //释放映射区return 0;
}
[root@localhost mmap]# ./fork_map_anon
child, *p = 2000
parent, *p = 0