mmap

存储映射IO

image
image

mmap函数

!image
其中文件的大小是小于等于真实文件大小,一般是等于。
权限一般是shared,private的话不会反应到磁盘上。
offset,默认0表示文件全部, 必须是4k的整数倍。

mmap基本使用

/*************************************************************************
	> File Name: pipe_test.c
	> Author: shaozheming
	> Mail: 957510530@qq.com
	> Created Time: 2022年02月27日 星期日 11时19分51秒
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/mman.h>

void sys_err(const char *str)
{
    perror(str);
    exit(1);
}

int main(int argc, char* argv[])
{
	char *p = NULL;
	int fd;
	int ret;

	fd = open("testMap", O_RDWR | O_CREAT | O_TRUNC, 0644);
	if(fd == -1)
		sys_err("open error\r\n");
	
	/* 扩展文件大小,因为0大小的文件不能用mmap  */
	ftruncate(fd, 20); //扩展大小为10
	int len = lseek(fd, 0, SEEK_END); //使用lseek获取文件的长度

	//void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
	p = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
	if(p == MAP_FAILED) {
		sys_err("map error\r\n");
	}

	//使用p进行文件读写操作
	strcpy(p, "hello mmap!"); //相当于写操作

	printf("----%s----\r\n",p);

	ret = munmap(p, len);
	if(ret == -1)
		sys_err("munmap error\r\n");

    return 0;
}

mmap使用注意事项

用于创建映射区的大小为0, 实际指定了非0的大小创建映射区,会出现总线错误

image

用于创建映射区的大小为0, 实际指定了大小为0创建映射区,会出现无效参数错误

用于创建映射区为只读,但是实际指定可读可写,会出现无效参数错误

image
ftruncate使用时,文件必须可写

如果上下都是只读,就会出现段错误,因为下面不能用strcopy写数据了

上下都是只写,也是错误的,但是上面要是可读可写就不会发生问题,因为mmap需要读权限

综上所述:mmap的读写权限小于等于文件的读写权限

文件描述符在mmap创建完毕之后即可close,只用mmap的首地址访问

offset不是4096的整数倍时,会出现Invalid argument,和mmu有关,mmu的最小单位是4096

越界

image
这种情况是属于不是申请的一块内存进行访问,但是不安全

munmap必须前后的首地址一样,否则会出错

将mmap设置成私有

使用od -tcx查看文件二进制,都是0,即只对内存有效,不会反应到磁盘上。
image

父子进程mmap通信

必须是shared通信
image
image
image
注意共享内存只能释放一次,是父子进程共用的

无血缘关系的mmap通信

写进程:
image
image
读进程:
image
image

mmap匿名映射

image
image
或者:
image
unix系统中
image

posted @ 2022-02-27 19:00  蘑菇王国大聪明  阅读(277)  评论(0编辑  收藏  举报