2:共享内存

内存映射文件

mmap,munmap,msync

void* mmap(
	void* addr,
	size_t len,
	// PROT_READ/PROT_WRITE/PROT_EXEC/PROT_NONE
	int prot,
	// MAP_PRIVATE/MAP_SHARED
	int flags,
	int fd,
	off_t offset);
int munmap(void* addr, size_t len);
int msync(
	void* addr, 
	size_t len, 
	// MS_ASYNC/MS_SYNC[针对MAP_SHARED映射返回地址范围内容的修改会同步更新到磁盘,这里显式触发一个更新到磁盘请求]		
	// MS_INVALIDATE[一个磁盘文件被多个进程以MAP_SHARED映射,其中一个做了改动.其他各个进程如映射相应范围也能看到改动后内容]
	int flags);
- 访问边界
内存映射以页面为单位.
对映射区域,
设其对应K个映射页面.
一般第K个页面会超过映射要求的可视范围.
在此范围内,允许进行读,写操作.
写操作,不会实际写入文件.
读操作,可以正常读.
对超出K页外的映射区域进行访问,会引发SIGSEGV信号.
对在映射区域内,但超过文件进行页面规整大小的区域进行访问,会引发SIGBUS

共享内存区对象

概述

Posix.1提供了两种在无亲缘关系进程间共享内存区的方法
- 内存映射文件
- 共享内存区对象
由shm_open打开一个Posix.1 IPC名字
所返回的描述符由mmap函数映射到当前进程的地址空间

在这里插入图片描述

shm_open和shm_unlink

Posix共享内存区涉及以下两个步骤要求
- 指定一个名字参数调用shm_open
以创建一个新的共享内存区对象或打开一个已存在的共享内存区对象
- 调用mmap把这个共享内存区映射到调用进程的地址空间
	#include <sys/mman.h>
	// 返回描述符
	int shm_open(
		const char*, 
		// O_RDONLY/O_RDWR/
		// O_CREAT/O_EXCL/O_TRUNC
		int, 
		//
		mode_t);
	// 删除一个名字不会影响对于底层支撑对象的现有引用
	// 直到对该对象引用全部关闭为止
	// 删除名字后,后续的open会失败
	int shm_unlink(const char*);

ftruncate和fstate函数

mmap时,普通文件或共享内存区对象大小都可用ftruncate修改
	#include <unistd.h>
	int ftruncate(int fd, off_t length);
- 对普通文件
如该文件大小大于length
额外的数据被丢弃掉
如该文件大小小于length
则该文件是否修改及其大小是否增长是未加说明的

一种保证正确方法,
先lseek到偏移为length-1处
写入1字节的数据
- 对共享内存区对象
ftruncate把该对象的大小设置成length字节


当打开一个已存在的共享内存区对象时,
可调用fstat获取有关该对象的信息
	#include <sys/types.h>
	#include <sys/stat.h>
	int fstat(int fd, struct stat* buf);
当fd指代一个共享内存区对象时,只有四个成员含有信息
	struct stat
	{
    
    
		...
		mode_t st_mode;
		uid_t st_uid;
		gid_t st_gid;
		off_t st_size;
		...
	};

猜你喜欢

转载自blog.csdn.net/x13262608581/article/details/110427677
今日推荐