mmap映射问题

1.多个进程mmap同一个文件会不会开辟多个内存?

2.munmap的时候,其他进程会不会受影响?

网上没有搜到自己想要的答案,只好自己做个实验

第一个问题代码没保存,思路是:两个进程同时mmap一个文件,同时往里面修改数据。

结果是:多个进程mmap同一个文件不会开辟多个内存。是共享同一片物理内存

int main(int argc, char **argv)
{
    int fd;
    char *mapped_mem;
    int flength = 1024;
    char buf[100] = "进程1:";

    fd = open("/home/dong/temp2", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

    mapped_mem = (char*) mmap(0, flength, PROT_READ, MAP_SHARED, fd, 0);
    printf("地址:%x\n",(void *)mapped_mem);
    //memset(mapped_mem,0,1024);//注意对于刚创建的文件还没有任何东西,这时候去读它会出现段错误
    for(int i=0; i<10; i++)
    {
        printf("%s\n", mapped_mem);
        sleep(1);
    }

    munmap(mapped_mem, flength);
    close(fd);
    return 0;
}
int main()
{
    int flength = 1024;
    int fd = open("/home/dong/temp2", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
                                            //S_IRUSR  Permits the file's owner to read it.
                                            //S_IWUSR  Permits the file's owner to write to it.
    printf("fd = %d\n",fd);
    char buf[100] = "进程2:";
    char *mapped_mem = (char*) mmap(0, flength, PROT_READ, MAP_SHARED, fd, 0);
    printf("地址:%x\n",(void *)mapped_mem);
    for(int i=0; i<5; i++)
    {   
        printf("%s\n", mapped_mem);
        sleep(1);
    }
    munmap(mapped_mem,flength);
    close(fd);
    return 0;
}

可以看出来一个进程munmap之后,另一个进程照样可以读那片内存,可见munmap并没有释放那片物理内存。到底在什么时候释放呢?我猜测和智能指针一样,当最后一个指向这片内存的指针被释放的时候,这片内存就被释放了(只是猜测)

### mmap 函数的使用方法 `mmap` 是一种用于创建内存映射文件区域的系统调用,在 POSIX 兼容的操作系统(如 Linux 和 macOS)中广泛使用。它允许进程将文件或其他对象映射到其地址空间,从而可以通过操作内存来读写文件内容。 以下是 `mmap` 的基本语法及其参数说明: #### 基本语法 ```c void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); ``` - **`addr`**: 请求的起始地址。通常设置为 `NULL`,让操作系统决定合适的地址[^1]。 - **`length`**: 映射区域的长度(字节单位)。必须是非零值[^2]。 - **`prot`**: 指定访问权限,可以是以下标志的组合: - `PROT_READ`: 可读。 - `PROT_WRITE`: 可写。 - `PROT_EXEC`: 可执行。 - `PROT_NONE`: 不可访问。 - **`flags`**: 控制行为的标志位,常见选项有: - `MAP_SHARED`: 修改会反映回文件。 - `MAP_PRIVATE`: 创建私有的副本,修改不会影响原文件。 - **`fd`**: 文件描述符,表示要映射的文件。如果不需要关联文件,则应指定特殊值(如 `-1`),并配合其他标志使用。 - **`offset`**: 文件中的偏移量,必须是对页大小取整的结果[^3]。 成功返回指向已映射区间的指针;失败则返回 `(void *) -1` 并设置 errno 来指示错误原因。 --- ### 示例代码 下面是一个简单的 C 程序示例,展示如何利用 `mmap` 将一个文件的内容映射到内存中,并对其进行读写操作。 ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> int main() { const char *filename = "example.txt"; int fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } // 设置文件大小以便有足够的数据映射 ftruncate(fd, 4096); void *mapped_region = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (mapped_region == MAP_FAILED) { perror("mmap"); close(fd); exit(EXIT_FAILURE); } // 向映射区域写入一些数据 snprintf(mapped_region, 4096, "Hello from mmap!"); printf("Mapped content: %s\n", (char*) mapped_region); munmap(mapped_region, 4096); // 解除映射关系 close(fd); // 关闭文件描述符 return EXIT_SUCCESS; } ``` 此程序完成如下功能: 1. 打开名为 `"example.txt"` 的文件或者新建该文件; 2. 使用 `ftruncate()` 调整文件尺寸至至少一页(这里设定了4KB),确保有足够的空间被映射; 3. 利用 `mmap()` 把这段范围内的文件内容加载进内存; 4. 对这个新建立起来的虚拟存储器位置进行字符串赋值以及打印验证; 5. 清理工作包括解除映射(`munmap`)和关闭文件句柄(close). --- ### 注意事项 当不再需要某个由 `mmap` 返回的内存区间时,应该显式地通过调用 `munmap(addr,length)` 来释放资源。否则可能导致未定义的行为发生,比如尝试再次映射同一段地址可能会失败等问题出现[^4]. 另外需要注意的是,尽管上面例子演示了共享模式下的情况 (`MAP_SHARED`), 如果希望更改只存在于当前进程中而不同步更新原始文件的话,则需改用复制方式即设定成 `MAP_PRIVATE`. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值