C 如何在同一共享内存段中正确使用多个变量
我试图在同一内存段中有2个整数。我的代码如下:C 如何在同一共享内存段中正确使用多个变量,c,shared-memory,C,Shared Memory,我试图在同一内存段中有2个整数。我的代码如下: int main() { int *a; int *b; int id; id = shmget(IPC_PRIVATE,10,0666); a = (int *) shmat(id, (void*)0, 0); b = (int *) shmat(id, (void*)0, 0); *a = 5; *b = 10; printf("%d\n",*a); printf("%d\n
int main()
{
int *a;
int *b;
int id;
id = shmget(IPC_PRIVATE,10,0666);
a = (int *) shmat(id, (void*)0, 0);
b = (int *) shmat(id, (void*)0, 0);
*a = 5;
*b = 10;
printf("%d\n",*a);
printf("%d\n",*b);
}
这个打印10次。谁能解释一下为什么会发生这种情况以及如何解决
额外问题:如果我使用char*而不是int,那么是否有必要执行malloc(sizeof(char)*10)或shmat调用以某种方式执行此任务
提前谢谢 首先,如果可能,您总是希望使用
malloc
而不是共享内存。
即使在进行IPC时,简单管道通常也更有效
回到你的问题,这里是对你的代码的一些解释
int main()
{
int *a;
int *b;
int id;
/* 'shmget' creates a shared memory segments of size 10,
basically reserving 10 bytes of RAM/Swap. This memory is not
accessible in your virtual memory yet */
id = shmget(IPC_PRIVATE,10,0666);
/* `shmat` maps the shared memory from above and makes it accessible in
your virtual memory. `a` points to the beginning of the memory segment */
a = (int *) shmat(id, (void*)0, 0);
/* Here we map the same shared memory again into a different place in the
virtual memory. But even if `a` and `b` points to different memory
addresses, those addresses are backed by the same segment in RAM/Swap */
b = (int *) shmat(id, (void*)0, 0);
*a = 5;
*b = 10; /* because `*a` and `*b` are backed by the same RAM/Swap, */
/* this will allso overwrite `*a` */
printf("%d\n",*a);
printf("%d\n",*b);
}
要解决这个问题,基本上有两种选择。它们都有两个共享内存段,一个用于a
,另一个用于b
。或者使一个段足够大,以容纳a
和b
指向段中的不同位置:
第一个解决方案:
/* This uses two segments */
int *a;
int *b;
int id1;
int id2;
id1 = shmget(IPC_PRIVATE,sizeof(int),0666);
id2 = shmget(IPC_PRIVATE,sizeof(int),0666);
a = (int *) shmat(id1, (void*)0, 0);
b = (int *) shmat(id2, (void*)0, 0);
/* This uses one segments */
int *a;
int *b;
int id;
/* Allocate enough memory for 2 int */
id = shmget(IPC_PRIVATE, 2*sizeof(int), 0666);
/* Map that memory into virtual memory space */
a = (int *) shmat(id, (void*)0, 0);
/* `a` points to the first int in a sequence of 2 ints, let `b` point to
the next one. */
b = a + 1;
第二种解决方案:
/* This uses two segments */
int *a;
int *b;
int id1;
int id2;
id1 = shmget(IPC_PRIVATE,sizeof(int),0666);
id2 = shmget(IPC_PRIVATE,sizeof(int),0666);
a = (int *) shmat(id1, (void*)0, 0);
b = (int *) shmat(id2, (void*)0, 0);
/* This uses one segments */
int *a;
int *b;
int id;
/* Allocate enough memory for 2 int */
id = shmget(IPC_PRIVATE, 2*sizeof(int), 0666);
/* Map that memory into virtual memory space */
a = (int *) shmat(id, (void*)0, 0);
/* `a` points to the first int in a sequence of 2 ints, let `b` point to
the next one. */
b = a + 1;
和往常一样,为了简洁起见,这段代码省略了错误检查。添加错误检查留给读者作为练习
对于额外的问题,无论是
malloc
还是任何共享内存函数都不关心您将在分配的内存中存储什么。他们只是给你一系列的char
。你的工作是计算你需要多少字符。(顺便说一句,sizeof(char)
始终为1)参考,所有IPC示例都是自然给出的,除非您首先对虚拟内存有了基本的了解,否则这可能没有任何意义。非常感谢!如果a是整数,b是字符呢?第二种解决方案有效吗?@PanD22,在分配的内存中混合数据类型是完全可能的。您只需正确计算偏移量。最简单的方法是将int
和char
放在结构中,并为该结构分配足够的内存。