内存映射文件示意图:
mmap函数:
功能:将文件或者设备空间映射到共享内存区。
原型
void*mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
参数
addr:要映射的起始地址,通常指定为NULL,让内核自动选择
len:映射到进程地址空间的字节数
prot:映射区保护方式
flags:标志
fd:文件描述符
offset:从文件头开始的偏移量
返回值:成功返回映射到的内存区的起始地址;失败返回-1
prot |
说明 |
PROT_READ |
页面可读 |
PROT_WRITE |
页面可写 |
PROC_EXEC |
页面可执行 |
PROT_NONE |
页面不可访问 |
flags |
说明 |
MAP_SHARED |
变动是共享的 |
MAP_PRIVATE |
变动是私有的 |
MAP_FIXED |
准确解释addr参数 |
MAP_ANONYMOUS |
建立匿名映射区,不涉及文件 |
munmap函数:
功能:取消mmap函数建立的映射
原型
intmunmap(void *addr, size_t len);
参数
addr:映射的内存起始地址
len:映射到进程地址空间的字节数
返回值:成功返回0;失败返回-1
msync函数:
功能:对映射的共享内存执行同步操作
原型
intmsync(void *addr, size_t len, int flags);
参数
addr:内存起始地址
len:长度
flags:选项
返回值:成功返回0;失败返回-1
flags |
说明 |
MS_ASYNC |
执行异步写 |
MS_SYNC |
执行同步写 |
MS_INVALIDATE |
使高速缓存的数据失效 |
map注意点:
映射不能改变文件的大小;
可用于进程间通信的有效地址空间不完全受限于被映射文件的大小;
文件一旦被映射后,所有对映射区域的访问实际上是对内存区域的访问。映射区域内容写回文件时,所写内容不能超过文件的大小。
共享内存数据结构:
structshmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
System V共享内存函数:
#include<sys/ipc.h>
#include<sys/shm.h>
intshmget(key_t key, size_t size, int shmflg);
void*shmat(int shmid, const void *shmaddr, int shmflg);
intshmdt(const void *shmaddr);
intshmctl(int shmid, int cmd, struct shmid_ds *buf);
shmget函数:
功能:用来创建共享内存
原型
intshmget(key_t key, size_t size, int shmflg);
参数
key:这个共享内存段名字
size:共享内存大小
shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1
shmat函数:
功能:将共享内存段连接到进程地址空间
原型
void*shmat(int shmid, const void *shmaddr, int shmflg);
参数
shmid:共享内存标识
shmaddr:指定连接的地址
shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1
shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示连接操作用来只读共享内存
shmdt函数:
功能:将共享内存段与当前进程脱离
原型
intshmdt(const void *shmaddr);
参数
shmaddr:由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段
shmctl函数:
功能:用于控制共享内存
原型
intshmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
shmid:由shmget返回的共享内存标识码
cmd:将要采取的动作(有三个可取值)
buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1
命令 |
说明 |
IPC_STAT |
把shmid_ds结构中的数据设置为共享内存的当前关联值 |
IPC_SET |
在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid_ds数据结构中给出的值 |
IPC_RMID |
删除共享内存段 |