linux系统编程--内存映射区概念及相应函数

0基本概念

1查看(系统的fifo文件):

  • man shm_overview
  • ls /dev/shm

2分类

  • 内存映射文件
  • 匿名内存映射(亲缘进程)
  • 共享内存区对象(非亲缘进程)
    linux系统编程--内存映射区概念及相应函数_第1张图片

3创建/打开文件int shm_open(const char *name, int oflag, mode_t mode)

3.1参数

参数 含义
name posix IPC名字,格式为/somename
oflag 标志
mode 权限

3.2标志

标志 作用
O_CREAT 没有该对象则创建
O_EXCL 如果O_CREAT指定,但name不存在,就返回错误
O_NONBLOCK 以非阻塞方式打开消息队列
O_RDONLY 只读
O_RDWR 读写
O_WRONLY 只写
O_TRUNC 若存在则截断

3.3权限

权限 作用
S_IWUSR 用户/属主写
S_IRUSR 用户/属主读
S_IWGRP 组成员写
S_IRGRP 组成员读
S_IWOTH 其他用户写
S_IROTH 其他用户读

3.5返回值

返回值 含义
-1 出错
其他 共享内存描述符
示例

4删除int shm_unlink(const char *name)

4.1参数

参数 含义
name posix IPC名字

4.3返回值

返回值 含义
-1 出错
0 成功

1mmap

1.1作用

  • 将磁盘文件的数据映射到内存,用户通过修改内存就能修改磁盘文件
    linux系统编程--内存映射区概念及相应函数_第2张图片
    映射区就在动态库加载区,然后mmap函数将此盘中的file文件直接映射到映射区 这时候多个进程访问同一个逻辑内存,进程直接访问内存,不用read()/write()非常方便

1.2函数原型

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

linux系统编程--内存映射区概念及相应函数_第3张图片

1.2.1权限

参数 含义
PROT_EXEC 页内容可以被执行
PROT_READ 页内容可以被读取 这个权限必须要有
PROT_WRITE 页可以被写入
PROT_NONE 页不可访问,不能与文件的打开模式冲突

1.2.2 映射对象的类型

参数 含义
MAP_SHARED 变动共享 (修改了内存数据会同步到磁盘)
MAP_PRIVATE 变动私有(修改了内存数据不会同步到磁盘)
MAP_ANON 匿名内存映射(匿名内存映射(亲缘进程))

1.2.3fd文件描述符

  • 磁盘中要映射文件的文件描述符。
  • 得到方式:open()

1.2.4映射区大小

  • 映射区的大小基本以4k的大小去增加,不能为零。
  • 基本就是映射文件大小

1.2.5off_t offset

  • 映射的时候文件指针的偏移量
  • 必须是4k的整数倍

1.2.6返回值

返回值 含义
MAP_FAILED 失败
非MAP_FAILED 共享内存地址

2munmap

int munmap(void *start,size_t length)

2.1 参数

  • start 映射内存起始地址 mmap的返回值

  • length 内存大小 mmap的第二个参数

    返回值

No. 返回值 含义
1 0 成功
2 -1 失败

2.2 示例

#include
#include
#include
#include
#include
#include 
#include 
#include
int main(){
	//打开一个文件
	int fd =open("english.txt",O_RDWR);
	int length=lseek(fd,0,SEEK_END);
	//创建文件内存映射区
	void *buf=mmap(NULL,length,PROT_READ,MAP_SHARED,fd,0);
	if(MAP_FAILED==buf){
		perror("nmap,error");
		return 1;
	}
	printf("%s\n",(char *)buf);
	munmap(buf,length);
return 0;
}

3文件控制

3.1获取文件信息int fstat(int fd,struct stat *buf)

3.1.1参数

参数 含义
fd 文件描述描述符
buf struct stat

3.1.2struct stat

No. 参数 含义
st_mode 权限
st_size 大小
st_uid 属主ID
st_guid 组ID

3.1.3返回值

返回值 含义
-1 出错
0 成功

3.1.4实例:获取文件大小

int fd=open(argv[optind],O_RDWR);
	if(-1==fd){
		perror("open error");
		return 1;
	}
	struct stat st;
	if(-1==fstat(fd,&st)){
		perror("查看错误");
		return 1;
	}
	printf("%s :size :%d\n",argv[optind],st.st_size);
	return 0;

3.2修改文件大小int ftruncate(int fd, off_t length)

3.2.1参数

参数 含义
fd 文件描述描述符
length 文件大小,如果原来的文件大小比参数length大,超过的部分删除。

3.2.2返回值

返回值 	|含义

–|--
-1 |出错
0 | 成功

3.3.3实例:设置文件大小

	if(-1==ftruncate(fd,new_size)){
		perror("修改错误");
		return 1;
	}
	if(-1==fstat(fd,&st)){
		perror("查看错误");
		return 1;
	}
	printf("%s :size :%d\n",argv[optind],st.st_size);
	close(fd);

4mmap注意事项

  • 如果对mmap的返回值buf进行++操作 munmap是否可以成功?

    • 不能
    • 可以 char *pt=buf; pt ++;
  • PROT_READ | PROT_WRITE什么意思?

    • 相当于权限为两个权限参数集合
  • 如果open的时候是O_CREAT,mmap时port参数指定PROT_READ | PROT_WRITE 时会怎样?

    • 出现错误mmap调用失败 open文件指定权限应该大于等于mmap第三个参数port指定的权限
  • 文件偏移量为1000时会怎麼样?

    • 错误无效参数
  • mmap什么情况调用失败?:

    • 第2个参数length=0;
    • 第3个参数port必须有PROT_READ
    • 第4个参数fd文件打开时的权限必须大于等于port
    • 第5个参数必须时4k(4096)的整数倍
  • 可以open的时候O_CREAT一个新文件来创建映射区吗?

    • 可以 但是因为创建完后文件大小为0,需要做文件扩展lseek()truncate(path,length)
  • mmap后关闭文件描述符,对mmap有没有影响

    • 没有
  • 对buf越界操作会怎麼样:

    • 此内存被占用->段错误
    • 此内存没有被占用 写的数据无法映射到文件将丢失

你可能感兴趣的:(系统编程)