我正在一个项目中,我需要在使用fork()API创建的进程之间共享大量std :: pair。程序开始时未知数组的大小。稍后,父进程将与子进程进行通信,以确定数组的大小。然后,它将通过调用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;
}
这是代码的输出: 父级:在地址0x7f00ae91b000处创建并验证了共享内存,数据大小:4096。
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
我正在Linux上运行它。 我在这里做错了什么?如果这不是执行此操作的最佳方法,那么不胜感激,您能指出更好的方法吗?
谢谢
答案 0 :(得分:0)
您不应该尝试取消映射mremap
之后的旧地址,因为旧地址已被取消映射,并且可能与新地址范围重叠。您的“旧内存未映射”消息将不会被打印,因为cout
已被缓冲,并且该进程在刷新该缓冲之前就死了。