尝试在不丢失当前信息的情况下扩展共享内存区域

Trying to extend shared memory region without losing current info

我正在尝试创建一个共享内存段,它将保存一组初始数据,但需要在稍后的某个时间在另一个数据块可用时进行扩展。我在这里阅读了几篇文章并尝试了一些东西,但我似乎缺少一些魔法并且可以使用一些建议。

这里有一个测试程序可以说明我遇到的问题:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <sys/mman.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
    void *addr, *resaddr;
    int *iarray;
    int fd;

    /* reserve a large address space - note that this doesn't ALLOCATE
     * anything. It simply tells the OS to reserve this much space
     * for us to eventually/potentially use. For this test case, we
     * will ask for 1GByte of space. We include the MAP_NORESERVE
     * flag to indicate that we don't want anything allocated, but
     * people report that this flag is ignored as PROT_NONE is
     * apparently sufficient for that purpose. */
    fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0660);
    addr = mmap(NULL, 1U << 30, PROT_NONE, MAP_ANONYMOUS | MAP_SHARED | MAP_NORESERVE, -1, 0);
    fprintf(stderr, "GOT ADDRESS %p\n", addr);
    iarray = (int*)addr;
    /* now get resources for a piece of that file */
    ftruncate(fd, 1U << 16);
    resaddr = mmap(addr, 1U << 16, PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 0);
    fprintf(stderr, "RESERVED ADDRESS %p\n", resaddr);
    /* put somthing into it */
    iarray[1024] = 1;
    fprintf(stderr, "iaddr[1024]: %d\n", iarray[1024]);
    /* increase the size */
    ftruncate(fd, 1U << 18);
    fsync(fd);
    resaddr = mmap(addr, (1U << 18) - (1U << 16), PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 1U << 16);
    fprintf(stderr, "EXTENDED RESERVED ADDRESS %p\n", resaddr);
    /* add something to that region */
    iarray[31000] = 2;
    fprintf(stderr, "\tiarray[1024]: %d\n\tiarray[31000]: %d\n", iarray[1024], iarray[31000]);
    exit(0);
}

运行 这会产生以下结果:

GOT ADDRESS 0x111396000
RESERVED ADDRESS 0x111396000
iaddr[1024]: 1
EXTENDED RESERVED ADDRESS 0x111396000
    iarray[1024]: 0
    iarray[31000]: 2

一切如我所料,唯一需要注意的是初始存储数据丢失(显然重置为零)。有没有人建议我应该采取哪些不同的方式来保留初始存储的数据?

据我了解,mmap() 的第三次调用不正确。

resaddr = mmap(addr, (1U << 18) - (1U << 16), PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 1U << 16);

应替换为

resaddr = mmap(addr + (1U << 16), (1U << 18) - (1U << 16), PROT_WRITE | PROT_READ, MAP_FIXED | MAP_SHARED, fd, 1U << 16);

(offset参数是文件中的偏移量,不是内存中的)