分类:
2009-12-17 08:42:36
下面说一下内存映射的步骤:
注意事项:
在修改映射的文件时, 只能在原长度上修改, 不能增加文件长度, 因为内存是已经分配好的.
II:[摘自]
内存映射文件(mmap)
内存映射文件是利用虚拟内存把文件映射到进程的地址空间中去,在此之后进程操作文
件,就像操作进程空间里的地址一样了,比如使用memcpy等内存操作的函数。这种方法能
够很好的应用在需要频繁处理一个文件或者是一个大文件的场合,这种方式处理IO效率比
普通IO效率要高。另外,UNIX把它做为内存共享来设计的。
UNIX中,头文件
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);