转:内存映射文件(mmap)和它的应用——共享内存(IPC)
作者: herosoft(http://herosoft.itpub.net)发表于: 2008.10.06 17:48
分类: Unix相关
出处: http://herosoft.itpub.net/post/5802/471760
---------------------------------------------------------------
内存映射文件是利用虚拟内存把文件映射到进程的地址空间中去,在此之后进程操作文
件,就像操作进程空间里的地址一样了,比如使用memcpy等内存操作的函数。这种方法能
够很好的应用在需要频繁处理一个文件或者是一个大文件的场合,这种方式处理IO效率比
普通IO效率要高。另外,UNIX把它做为内存共享来设计的。
UNIX中,头文件<sys/mman.h>中有与此相关的函数定义。mman==super man :)。
1、创建一个内存映射区域
void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off);
addr | 映射区首地址,你想自己定义的时候使用。一般使用NULL,然后系统自动分配一个合适地址。 |
len | 映射的长度, 单位byte |
prot | 说明映射区访问属性:读、写、执行、不可访问 可 PROT_READ,PROT_WRITE,PROT_EXEC,PROT_NONE 不能超越它所映射的文件的权限 |
flag | MAP_SHARED 这个标志说明文件映射是共享的,也就是说进程改变了内存映射,也就会影响到文件。 MAP_PRIVATE 这个标志说明文件映射不共享,打开文件映射的进程只能改变的是这个文件的一个副本。 |
filedes | 文件描述符号 |
off | 隐射位置的偏移量,设置为0的话,就映射文件的0-len个字节 |
返回 | 映射区域的首地址 |
2、取消文件映射
int munmap(caddr_t addr,size_t len);
addr | 内存隐射的地址。mmap返回的地址。 |
len | 隐射的字节数。 |
返回 | 成果0,失败负 |
使用MAP_PRIVATE的映射改变将不被写回文件。
3、内存映射和文件的同步
int msync(void *addr, size_t len,int flags);
addr | 内存映射地址 |
len | 长度 |
flags | MS_ASYNC,MS_SYNC,MS_INVALIDATE。 MS_ASYNC,异步写,调用后就返回不等待写完,MS_SYNC则等待写完才返回。 MS_INVALIDATE,写完之后,内存映射中与文件不同的数据将无效,取而代之的是文件中的数据。 |
返回 | 成功0,失败负 |
4、创建共享内存区
这个信号量比较相同。
int shm_open(const char *name ,into flag, mode_t mode);
对比:
sem_t *sem_open(const char *name,int oflag,/*mode_t mode,unsigned int value*/);
这个地方就可以解释sem_open函数的文件名有什么用了。使用shem_open创建共享文件,
使用mmap使内存这个文件映射,实现共享内存,然后再使用信号量来同步。这个搭配可算是完美!
name | 共享区名,需要绝对路径 |
flag | 和open文件一样,O_RDONLY O_RDWR O_CREAT O_TRUNC |
mode | 权限位置,和文件相同。只能在O_CREAT下使用 |
返回 | 成功返回一个文件描述字,失败负 |
既然它是一种文件,那么我们对文件操作的函数, fstat lstat read wirte ftruncate 这些函数都可以尝试着对他使用一把。不成功便成人嘛!
5、删除共享内存区
int shm_unlink(const char *name);
Trackback: http://hi.baidu.com/xiaoke830/blog/item/204596ef58e6a934adafd5be.html


