mmap
mmap
函数使得进程之间通过映射同一个文件实现共享内存。进程可以像访问内存一样对文件进行访问,不必调用read
、write
等操作。
mmap
的函数原型如下,其返回值为文件映射到进程空间的地址:
void *mmap ( void *addr, size_t len, int prot, int flags, int fd, off_t offset );
addr
:一般设置为NULL
。len
:映射到进程地址空间的字节数,从被映射文件头后offset
个字节开始算起。prot
:共享内存的访问权限。可以取如下几个值,也可以进行或
计算:
权限 | 说明 | 权限 | 说明 |
---|---|---|---|
PROT_READ |
可读 | PROT_WRITE |
可写 |
PROT_EXEC |
可执行 | PROT_NONE |
不可访问 |
flags
:可以取MAP_SHARED
或MAP_PRIVATE
。offset
:一般设为0
,表示从文件头开始映射。fd
:映射到进程空间的文件描述符,有如下2
种获取方式:
- 一般由
open
打开一个文件后返回。 - 可以指定为
-1
,但同时flags
要与MAP_ANONYMOUS
进行或
运算,表明进行的是匿名映射
。
匿名映射
不涉及具体的文件名,避免了文件的创建及打开,只能用于具有亲缘关系的进程。
创建共享内存
创建共享内存有如下2
种方式:
- 使用普通文件提供的内存映射:
- 适用于任何进程之间。
- 需要打开或创建一个文件,然后再调用
mmap
:
- 使用特殊文件提供匿名内存映射:
- 适用于具有亲缘关系的进程。
- 在父进程中先调用
mmap
,然后调用fork
。
munmap
使用munmap
在进程地址空间中解除映射关系:
int munmap ( void *addr, size_t len );
addr
是调用mmap
时返回的地址。len
是映射区的大小。
在调用munmap
后,共享内存中的内容将被写到fd
对应的文件中。
普通映射
两个进程通过映射普通文件实现共享内存通信:
map_write.c
如下:
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include "stdio.h"
#include "string.h"
typedef struct {
char name[4];
int age;
} people;
int main ( int argc, char **argv ) {
int fd, i;
people *p_map;
char temp;
fd = open ( argv[1]