mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存,但并不是完全为了用于共享内存而设计的。它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作。而Posix或系统V的共享内存IPC则纯粹用于共享目的,当然mmap()实现共享内存也是其主要应用之一。
mmap把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接用指针来做而不需要read/write函数。
-----------------------------------------------------------------------------------------------
#include
void *mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off);
int munmap(void *addr, size_t len);------------------------------------------------------------------------------------------------参数说明:1.addr,若addr==NULL,内核会自己在进程地址空间中选择合适的地址建立映射。如果addr不是NULL,则给内核一个提示应该从什么地址开始映射,内核会选择addr之上的某个合适的地址开始映射。建立映射后,真正的映射首地址通过返回值可以得到。2.len,需要映射的那一部分文件的长度,这也就决定了mmap没办法增加文件的长度。3.off,表示从文件的什么位置开始映射,必须是页大小的整数倍(在32位体系统结构上通常是4K)。4.filedes是代表该文件的描述符。5.prot参数有四种取值:PROT_EXEC表示映射的这一段可执行,例如映射共享库
PROT_READ表示映射的这一段可读
PROT_WRITE表示映射的这一段可写
PROT_NONE表示映射的这一段不可访问
6.flag参数有很多种取值
MAP_SHARED多个进程对同一个文件的映射是共享的,一个进程对映射的内存做了修改,另一个进程也会看到这种变化。
MAP_PRIVATE多个进程对同一个文件的映射不是共享的,一个进程对映射的内存做了修改,另一个进程并不会看到这种变化,也不会真的写到文件中去。
如果mmap成功则返回映射首地址,如果出错则返回常数MAP_FAILED。当进程终止时,该进程的映射内存会自动解除,也可以调用munmap解除映射。munmap成功返回0,出错返回-1。
-----------------------------------------------------------------------------------------
int msync(const void *start, size_t length, int flags);
-----------------------------------------------------------------------------------------
如果开启记忆体对映是希望写入档案中,那麽修改过的记忆体会在一段时间内与档案稍稍有点不同。如果您希望立即将资料写入档案中,可使用msync。
start为记忆体开始位置,length为长度。
flags则有三个:
MS_ASYNC : 请Kernel快将资料写入。
MS_SYNC : 在msync结束返回前,将资料写入。
MS_INVALIDATE : 让核心自行决定是否写入,仅在特殊状况下使用。
一个简单的实验:
$ vi hello
(编辑该文件的内容为“hello”)
$ od -tx1 -tc hello
0000000 68 65 6c 6c 6f 0a
h e l l o \n
0000006现在用如下程序操作这个文件#include
#include
#include
int main(void)
{
int *p;
int fd = open("hello", O_RDWR);
if (fd < 0) {
perror("open hello");
exit(1);
}
p = mmap(NULL, 6, PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
perror("mmap");
exit(1);
}
close(fd);
p[0] = 0x30313233;
munmap(p, 6);
return 0;
}
然后再查看这个文件的内容:$ od -tx1 -tc hello
0000000 33 32 31 30 6f 0a
3 2 1 0 o \n
0000006
阅读(919) | 评论(0) | 转发(0) |