linux下使用进程间使用共享内存,其中一方改变共享内存大小后,另一方的映射会有效吗?
答案是否定的
比如在一个进程1里开了一个1024的共享内存,在另一个进程2里把共享内存的大小设置为1024*1024*1000
在进程1里对1024*1024*1000-1 访问报段错误,实际上,在我测试的环境里在对1024*16访问时报错,对1024*16-1访问都不会报错
这里猜测共享内存是以16*1024为分配粒度的
但是在一个进程1里开了一个1024的共享内存,在另一个进程2里把共享内存的大小设置为1024*16,对进程2的的
Ptr, Ptr[0], Ptr[1], Ptr[2], Ptr[3], Ptr[1024*16-4], Ptr[1024*16-3], Ptr[1024*16-2], Ptr[1024*16-1]进行赋值
然后在进程1里获取
Ptr, Ptr[0], Ptr[1], Ptr[2], Ptr[3], Ptr[1024*16-4], Ptr[1024*16-3], Ptr[1024*16-2], Ptr[1024*16-1]的值,
Ptr, Ptr[0], Ptr[1], Ptr[2], Ptr[3]能获取到进程2的值
Ptr[1024*16-4], Ptr[1024*16-3], Ptr[1024*16-2], Ptr[1024*16-1]则不能获取到进程2的值,保持不变
因此,可以在共享内存的头部记录一下共享内存的大小,如果其中一个进程改变了共享内存的大小,在另一个进程里通过读取头部记录记录的值正确得知共享内存被修改为了多大,从而用mmap重新来做映射,这样就不会丢失数据了
void* test_pull_stream_shm_create(void *)
{
shm_unlink("1111");
int Fd = shm_open("1111", O_CREAT|O_RDWR|O_TRUNC, 0777);
if (Fd<0)
{
jtprintf("shm_open error, %s", strerror(errno));
return NULL;
}
if (ftruncate(Fd, 1024)<0)
{
jtprintf("ftruncate Fd %d error, %s\n", Fd, strerror(errno));
return NULL;
}
char* Ptr = (char*)mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, Fd, 0);
jtprintf("mmap Ptr %p", Ptr);
Ptr[0] = 20;
Ptr[1] = 21;
Ptr[2] = 22;
Ptr[3] = 23;
Ptr[1024*16-4]=81;
Ptr[1024*16-3]=82;
Ptr[1024*16-2]=83;
Ptr[1024*16-1]=84;
Ptr[512] = 0;
Ptr[1020] = 99;
Ptr[1021] = 100;
Ptr[1022] = 101;
Ptr[1023] = 102;
jtprintf("mmap Ptr %p, %d %d %d %d, %d %d %d %d", Ptr, Ptr[0], Ptr[1], Ptr[2], Ptr[3], Ptr[1024*16-4], Ptr[1024*16-3], Ptr[1024*16-2], Ptr[1024*16-1]);
getchar();
/*
if (ftruncate(Fd, 1024*1024*1000)<0)
{
jtprintf("ftruncate Fd %d error, %s\n", Fd, strerror(errno));
return NULL;
}
Ptr = (char*)mmap(NULL, 1024*1024*1000, PROT_READ | PROT_WRITE, MAP_SHARED, Fd, 0);
jtprintf("mmap Ptr %p", Ptr);
*/
jtprintf("mmap Ptr %p, %d %d %d %d, %d %d %d %d", Ptr, Ptr[0], Ptr[1], Ptr[2], Ptr[3], Ptr[1024*16-4], Ptr[1024*16-3], Ptr[1024*16-2], Ptr[1024*16-1]);
getchar();
Ptr[0] = 20;
Ptr[1] = 21;
Ptr[2] = 22;
Ptr[3] = 23;
Ptr[512] = 0;
Ptr[1020] = 99;
Ptr[1021] = 100;
Ptr[1022] = 101;
Ptr[1023] = 102;
Ptr[1024] = 0;
Ptr[1024*2] = 0;
Ptr[1024*4] = 0;
Ptr[1024*8] = 0;
Ptr[1024*12] = 0;
Ptr[1024*16-1] = 0;
Ptr[1024*16] = 0;
Ptr[1024*32] = 0;
Ptr[1024*64] = 0;
Ptr[1024*128] = 0;
Ptr[1024*256] = 0;
Ptr[1024*512] = 0;
Ptr[1024*1024] = 0;
Ptr[1024*1024*500] = 0;
//Ptr[1024*1024*1000-1];
jtprintf("Ptr[1024*1024*1000-1] %d", Ptr[1024*1024*1000-1]);
return NULL;
}
void* test_pull_stream_shm(void *)
{
int Fd = shm_open("1111", O_RDWR, 0777);
if (Fd<0)
{
jtprintf("shm_open error, %s", strerror(errno));
return NULL;
}
if (ftruncate(Fd, 1024)<0)
{
jtprintf("ftruncate error, %s\n", strerror(errno));
return NULL;
}
char* Ptr = (char*)mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, Fd, 0);
jtprintf("mmap Ptr %p", Ptr);
if (ftruncate(Fd, 1024*16)<0)
{
jtprintf("ftruncate error, %s\n", strerror(errno));
return NULL;
}
Ptr = (char*)mmap(NULL, 1024*16, PROT_READ | PROT_WRITE, MAP_SHARED, Fd, 0);
jtprintf("mmap Ptr %p", Ptr);
if (ftruncate(Fd, 1024*1024*1000)<0)
{
jtprintf("ftruncate error, %s\n", strerror(errno));
return NULL;
}
Ptr = (char*)mmap(NULL, 1024*1024*1000, PROT_READ | PROT_WRITE, MAP_SHARED, Fd, 0);
jtprintf("mmap Ptr %p", Ptr);
Ptr[1024*1024*500] = 0;
Ptr[1024*1024*1000-1] = 111;
Ptr[0] = 70;
Ptr[1] = 71;
Ptr[2] = 72;
Ptr[3] = 73;
Ptr[1024*16-4]=1;
Ptr[1024*16-3]=2;
Ptr[1024*16-2]=3;
Ptr[1024*16-1]=4;
jtprintf("mmap Ptr %p, %d %d %d %d, %d %d %d %d", Ptr, Ptr[0], Ptr[1], Ptr[2], Ptr[3], Ptr[1024*16-4], Ptr[1024*16-3], Ptr[1024*16-2], Ptr[1024*16-1]);
getchar();
munmap(Ptr, 1024*1024*1000);
close(Fd);
shm_unlink("1111");
return NULL;
}