内存映射mmap函数的理解

定义:

mmap,从函数名就可以看出来这是memory map, 即地址的映射, 是一种内存映射文件的方法。

mmap:将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。mmap()系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以向访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。

mmap函数及其参数:

 #include 

 void *mmap (void *addr, size_t length, int prot, int flags, int fd, off_t offset);

char *p = NULL;
p =(char *)mmap(NULL,len,PROT_WRITE|PROT_READ,MAP_SHARED,fd,0);

这个着重分析一下mmap函数的参数元素意思:

1、NULL表示文件被映射到进程空间的起始地址,一般被指定一个空指针,此时选择起始地址的任务留给内核来完成。

2、len表示映射到调用进程地址空间的字节数,它从被映射文件开头offset个字节开始算起。

3、PROT_WRITE|PROT_READ表示指定共享内存的访问权限
4、flags参数表示由以下几个常值指定:MAP_SHARED (读写自由), MAP_PRIVATE(私有映射)。
5、fd为即将映射到进程空间的文件描述符,一般由open()返回。
6、offset参数一般设为0,表示从文件头开始映射, 代表偏移量。(偏移量必须是4096的整数倍!!!)

进程启动映射过程,并在虚拟地址空间中为映射创建虚拟映射区域

1、进程在用户空间调用库函数mmap,原型:void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);

2、在当前进程的虚拟地址空间中,寻找一段空闲的满足要求的连续的虚拟地址

3、为此虚拟区分配一个vm_area_struct结构,接着对这个结构的各个域进行了初始化

4、将新建的虚拟区结构(vm_area_struct)插入进程的虚拟地址区域链表或树中

最初我一直以为该映射区若以MAP_SHARED (读写自由)去设定时,父子进程映射的地址是不同的。因为这里映射的也是一块虚拟映射区域,所以其实是相同的一块虚拟地址,只是它们的实际物理地址是不同的!!!

代码验证:

#include
#include
#include
#include
#include
#include
#include
#include
#include

int main()
{
	int fd;
	fd = open("2.txt",O_RDWR|O_CREAT|O_TRUNC,0660);
	if(-1 == fd)
	{
		perror("error");
		exit(1);
	}

	ftruncate(fd,4);
	int len = lseek(fd,0,SEEK_END);
	printf("文件大小为%d\n",len);

	int *p = NULL;
//	p =(int *)mmap(NULL,len,PROT_WRITE|PROT_READ,MAP_SHARED,fd,0);
	p =(int *)mmap(NULL,len,PROT_WRITE|PROT_READ,MAP_PRIVATE,fd,0);
	pid_t pid = fork();
	if(pid == -1)
	{
		perror("error");
		exit(1);
	}
	else if(0 == pid)
	{
		printf("我是子进程\n");
		*p = 1100;
		printf("内存映射的数值为:%d\n",*p);
		printf("内存映射地址为:%p\n",p);
	}
	else
	{
		wait(NULL);
		printf("我是父进程\n");
		*p = 9111;
		printf("内存映射的数值为:%d\n",*p);
		printf("内存映射地址为:%p\n",p);	
	}
	close(fd);
	return 0;
}

运行结果:

内存映射mmap函数的理解_第1张图片

有点困了,明天再写!!!

你可能感兴趣的:(Linux学习笔记,linux)