欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-20 14:26:27
...

0基本概念

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

  • man shm_overview
  • ls /dev/shm

2分类

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

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系统编程--内存映射区概念及相应函数
    映射区就在动态库加载区,然后mmap函数将此盘中的file文件直接映射到映射区 这时候多个进程访问同一个逻辑内存,进程直接访问内存,不用read()/write()非常方便

1.2函数原型

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

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

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<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<sys/mman.h>
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越界操作会怎麼样:

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