使用mmap映射共享内存大小超过ftruncate完成的set size

问题描述 投票:1回答:1

基于以下来源,我几乎没有问题:

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>

int g;
int main(void) {
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(fd, sizeof(int)); // set size by sizeof(int)
    int *p1 = mmap(NULL, 10*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0); //now map  10*sizeof(int).
    if (p1== MAP_FAILED) {
        printf("*****************error");
    }
    *p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);
    if (p1== MAP_FAILED) {
        printf("*****************error");
    }

    *p1=89;

    return g;
}

问题1:当我将size设置为size_of(int)然后映射10 * size_of(int)时,为什么我没有看到任何错误

问题2:这里创建了多少共享内存实例?我的意思是只有一个共享内存创建或两个,因为我做了两次mmap?

谢谢

c ubuntu posix shared-memory
1个回答
1
投票

鉴于代码

#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>

int g;
int main(void) {
    int fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(fd, sizeof(int)); // set size by sizeof(int)
    int *p1 = mmap(NULL, 10*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0); //now map  10*sizeof(int).
    *p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);
    if (!p1){
        printf("*****************error");
    }
    *p1 = g;
    *p1=89;

    return g;
}

问题1:当我将size设置为size_of(int)然后映射10 * size_of(int)时,为什么我没有看到任何错误

因为您没有检查mmap()的返回值,所以您不知道是否发生了错误。通过立即再次呼叫mmap()

*p1 = mmap(NULL, 8*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd,0);

您屏蔽了第一个mmap()调用中的任何潜在错误,并且还泄漏了已成功分配的任何内存。

问题2:这里创建了多少共享内存实例?我的意思是只有一个共享内存创建或两个,因为我做了两次mmap?

如果第一次调用成功,则映射两个内存段。如果失败,只有第二次成功后才映射一个。

如果第一次调用成功,则泄露内存。

请注意,如果您尝试写入mmap()'d段超过使用ftruncate()设置的文件大小的末尾,则不会导致文件增长。每the POSIX mmap() documentation

请注意,超出对象末尾的引用不会扩展对象,因为大多数虚拟内存硬件无法准确确定新端。相反,可以通过ftruncate()直接操作大小。

在Linux上,尝试访问映射文件末尾之外的mmap()数据可能会导致您的进程receiving a SIGBUS signal

© www.soinside.com 2019 - 2024. All rights reserved.