linux下进程间使用共享内存,其中一方改变共享内存大小后,另一方的映射会有效吗?

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;
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值