mmap()
是一个强大的系统调用,用于在进程的虚拟地址空间中创建内存映射。它可以将文件或设备映射到内存,或者创建匿名内存区域用于进程间通信(IPC)。下面将详细解释 mmap()
的三个主要用途,并提供相应的示例代码。
(1)进程创建匿名的内存映射
把内存的物理页映射到进程的虚拟地址空间
详细解释
匿名内存映射是一种不与任何文件关联的内存映射。它通常用于动态分配内存或在父子进程间共享内存。使用匿名内存映射时,操作系统会为映射区域分配物理内存页,并将其映射到进程的虚拟地址空间中。这种方法比传统的 malloc()
更灵活,尤其适用于需要在进程间共享数据的场景。
主要特点:
-
无文件关联:匿名内存映射不依赖于任何文件,适用于动态内存分配。
-
进程间共享:通过在父子进程之间共享映射,可以实现高效的进程间通信。
-
灵活性:可以控制映射区域的大小和权限。
示例代码
以下示例展示了如何使用 mmap()
创建一个匿名内存映射,并在父子进程间共享数据。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> #include <string.h> #include <sys/wait.h> int main() { // 创建匿名内存映射,大小为一个整数 int *shared_mem = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (shared_mem == MAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); } // 初始化共享内存 *shared_mem = 0; printf("Initial value: %d\n", *shared_mem); pid_t pid = fork(); if (pid < 0) { perror("fork"); munmap(shared_mem, sizeof(int)); exit(EXIT_FAILURE); } else if (pid == 0) { // 子进程:修改共享内存的值 *shared_mem = 42; printf("Child process updated value to: %d\n", *shared_mem); // 解除映射并退出 munmap(shared_mem, sizeof(int)); exit(EXIT_SUCCESS); } else { // 父进程:等待子进程结束 wait(NULL); // 读取共享内存的值 printf("Parent process reads value: %d\n", *shared_mem); // 解除映射 munmap(shared_mem, sizeof(int)); } return 0; }
代码解释
-
创建匿名内存映射:
int *shared_mem = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
-
NULL
:让操作系统选择映射的起始地址。 -
sizeof(int)
:映射区域的大小。 -
PROT_READ | PROT_WRITE
:映射区域的保护标志,允许读写。 -
MAP_SHARED | MAP_ANO
-