Memory 使用mremap调整mmap共享内存的大小失败

Memory 使用mremap调整mmap共享内存的大小失败,memory,fork,mmap,Memory,Fork,Mmap,我正在从事一个项目,在这个项目中,我需要在使用fork()API创建的进程之间共享一个大型std::pairs数组。在程序开始时,阵列的大小未知。稍后,父进程将与子进程通信以确定数组的大小。然后,它将通过调用mremap()API来调整共享内存空间的大小。到目前为止,我还没有使用mmap和mremap的运气。 在我看来,当新大小超过4096字节(系统的页面大小?)时,mremap()会失败 我创建了一个小例子来帮助我更好地理解这个问题。这段代码使用mmap()创建共享内存,然后使用mremap在

我正在从事一个项目,在这个项目中,我需要在使用fork()API创建的进程之间共享一个大型std::pairs数组。在程序开始时,阵列的大小未知。稍后,父进程将与子进程通信以确定数组的大小。然后,它将通过调用mremap()API来调整共享内存空间的大小。到目前为止,我还没有使用mmap和mremap的运气。 在我看来,当新大小超过4096字节(系统的页面大小?)时,mremap()会失败

我创建了一个小例子来帮助我更好地理解这个问题。这段代码使用mmap()创建共享内存,然后使用mremap在多个步骤中增加其大小。本例中只有一个流程。 我还将请求的共享内存大小四舍五入到4096字节

#include <iostream>
#include <sys/types.h> /* pid_t */
#include <sys/wait.h>
#include <unistd.h>  /* _exit, fork */
#include <stdlib.h>  /* exit */
#include <errno.h>   /* errno */
#include <time.h>       /* time */
#include <sys/mman.h>
#include <vector>
#include <map>
#include <string.h>
#include  <sys/ipc.h>
#include  <sys/shm.h>
#define page_size 4096
#define def_size  32

void write_shmem (long *shm_ptr, long npt)
{
    for (long pt = 0; pt < npt ; ++pt)
    {
        shm_ptr[pt] = 77;
        //std::cout << "shm_ptr[" << pt << "] = " <<  shm_ptr[pt] << "\n";
    }
}

long read_shmem (long *shm_ptr, long npt)
{
    long bad_indx = -1;
    for (long pt = 0; pt < npt ; ++pt)
    {
        if (shm_ptr[pt] != 77)
        {
            bad_indx = pt;
            break;
        }
    }
    return bad_indx;
}

int main ()
{

    void * add;
    long *shm_arcs;
    long padding = 0;
    long init_shmem_size = sizeof (long) *def_size;
    long resid = init_shmem_size % page_size;
    if (resid!=0) padding = page_size  - (init_shmem_size % page_size);
    //std::cout << " requested " << init_shmem_size << " bytes, translated to " << padding+init_shmem_size << "\n";
    init_shmem_size +=padding;
    add = mmap(NULL, init_shmem_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); // initial size is set to npt.
    if (add == MAP_FAILED)
    {
        std::cout << "Mapped failed at parent \n";
        exit(-1);
    }
    shm_arcs = (long *) add;
    write_shmem (shm_arcs, def_size);
    long bd = read_shmem (shm_arcs, def_size);

    if (bd!=-1)
    {
        std::cout << "Shmem test failed at " << bd << "\n";
        exit(-1);
    }

    std::cout<<"Parent: shared memory is created and verified at address " << shm_arcs <<" data size: " << init_shmem_size << ".\n ";


    long *shm_new = shm_arcs;
    long nsize = def_size;
    for (int i = 0; i< 1000; i ++)
    {
        nsize += def_size;
        long bsize = nsize*sizeof(long);
        if ((bsize % page_size)!=0) padding = page_size  - (bsize % page_size);
        else padding = 0;
        //std::cout << nsize << " elements requested " << bsize << " bytes, translated to " << padding+bsize << "\n";
        bsize+=padding;
        add = mremap(shm_new, init_shmem_size, bsize , MREMAP_MAYMOVE);
        if (add != shm_new)
        {
            std::cout << "Old mem unmapped ---------------";
            munmap(shm_new, init_shmem_size);
        }
        if (add == MAP_FAILED)
        {
            std::cout << "Mapped failed at parent  at " << i << "\n";
            exit(-1);
        }
        shm_new = (long *) add;

        write_shmem (shm_new, nsize);
        long bd = read_shmem (shm_arcs, nsize);
        if (bd!=-1)
        {
            std::cout << "Shmem test failed at " << bd << "\n";
            exit(-1);
        }

        std::cout<< i << " - Parent: shared memory is created and verified at address " << shm_new <<" with " << nsize << " elements, data size : " << bsize <<  ".\n ";

        init_shmem_size = bsize;
    }
    return 0;
}
我正在Linux上运行它。 我做错了什么?如果这不是最好的方法,我很感激你能指出一个更好的方法吗


谢谢

您不应该尝试在
mremap
之后取消映射旧地址,因为它已经取消映射,并且可能与新地址范围重叠。“旧内存未映射”消息将不会打印,因为
cout
已被缓冲,并且进程在刷新缓冲区之前终止。

您不应尝试在
mremap
之后取消映射旧地址,因为它已经未映射,并且可能与新地址范围重叠。由于
cout
已被缓冲,并且进程在刷新缓冲区之前终止,因此不会打印您的“Old mem unmapped”(旧内存未映射)消息

0 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 64 elements, data size : 4096.
 1 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 96 elements, data size : 4096.
 2 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 128 elements, data size : 4096.
 3 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 160 elements, data size : 4096.
 4 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 192 elements, data size : 4096.
 5 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 224 elements, data size : 4096.
 6 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 256 elements, data size : 4096.
 7 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 288 elements, data size : 4096.
 8 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 320 elements, data size : 4096.
 9 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 352 elements, data size : 4096.
10 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 384 elements, data size : 4096.
11 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 416 elements, data size : 4096.
12 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 448 elements, data size : 4096.
13 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 480 elements, data size : 4096.
14 - Parent: shared memory is created and verified at address 0x7f00ae91b000 with 512 elements, data size : 4096.
Bus error