内存映射文件
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);
(1). 访问边界
内存映射以页面为单位.对映射区域,设其对应k
个映射页面.一般第k
个页面会超过映射要求的可视范围.对页内超出范围部分,允许进行读,写操作.写操作,不会实际写入文件.读操作,可以正常读.对超出K
页外的映射区域进行访问,会引发SIGSEGV
信号.
共享内存区对象
概述
Posix.1
提供了两种在无亲缘关系进程间共享内存区的方法
(1). 共享文件映射
(2). 共享内存映射
由shm_open
打开一个Posix.1 IPC
名字,所返回的描述符由mmap
函数映射到当前进程的地址空间
shm_open和shm_unlink
Posix
共享内存区涉及以下两个步骤要求
(1). 指定一个名字参数调用shm_open
以创建一个新的共享内存区对象或打开一个已存在的共享内存区对象
(2). 调用mmap
把这个共享内存区映射到调用进程的地址空间
#include <sys/mman.h>
// 返回描述符
int shm_open(...);
// 删除一个名字不会影响对于底层支撑对象的现有引用,直到对该对象引用全部关闭为止
// 删除名字后,后续的open会失败
int shm_unlink(const char*);
ftruncate和fstate函数
mmap
时,普通文件或共享内存区对象大小都可用ftruncate
修改
#include <unistd.h>
int ftruncate(int fd, off_t length);
(1). 对普通文件
如该文件大小大于length
,额外的数据被丢弃掉
如该文件大小小于length
,则该文件是否修改及其大小是否增长是未加说明的
一种保证正确方法,先lseek
到偏移为length-1
处,写入1
字节的数据
(2). 对共享内存区对象
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;
...
};