使用`shm_open()`在两个进程之间共享一个带有指针的结构

时间:2015-01-01 22:23:29

标签: c arrays struct posix shared-memory

我有以下结构,

typedef struct arrays {
    int *array;
    int max;
    int min;
} array;

*array指向动态分配的数组,maxmin包含数组中的最大和最小数字。

我需要在两个进程之间共享一个实例(我可以在C中使用'实例'这个词吗?),我应该首先使用shm_open()来分配{{1}指向的数组第二个用于分配结构本身,还是有更好的方法来实现相同的结果?

3 个答案:

答案 0 :(得分:3)

我不知道它是否更好但你只能通过一次分配来完成:分配一个大缓冲区以包含结构数组,然后使array指向缓冲区+结构的大小。

答案 1 :(得分:2)

你需要这样做。

  1. 在每个进程中使用 shm_open 来获取文件描述符。您必须在每个进程中传递shm_open相同的名称。该名称是共享内存区域与其他共享内存区域的区别。名称必须以斜杠开头:"/somename"
  2. 使用步骤1中获取的文件描述符来调用 mmap
  3. mmap返回的地址是您的共享内存地址。它在每个过程中都是随机的和不同的。
  4. 由于3,您不能在共享内存区域内使用指针。您需要从共享内存的开头使用整数偏移,或者完全取消间接。例如,将整个共享内存区域视为整数数组。前两个单元格保留minmax,实际数字在此之后开始。
  5. mmap将返回可用内存,您无需静态或使用malloc分配任何缓冲区。

答案 2 :(得分:1)

好吧,第一个asnwer就像你告诉医生“当我这样做时疼痛”并且医生说“然后不要这样做!”

假设你对此有意,请记住shm_open使得一块内存可以共享:如果你在共享的内存中有一个指向malloc内存的指针,那么它将成为指向某些内存的指针就其他进程而言,堆中的随机地址。您需要分配整个缓冲区,整个内存块,然后共享它。

<强>更新

根据下面的问题,如果你想在运行时分配缓冲区 ,那么规范的方法是:

#define HOWBIGISMYBUFFER (3*GAZILLION)
char * buf;
if((buf = malloc(HOWBIGISMYBUFFER)) == 0){
    /* make splodey noises and terminate */
}
/* now you have your buffer */

其中,GAZILLION当然在其他地方定义。那就是说,你不想那样做。你想要实现的是一个可以共享的静态内存块,并在堆上分配它会让你遇到各种非常难以跟踪的bug。 (考虑一下,例如,你在程序A中分配内存,将它共享给程序B,程序B然后通过缓冲区溢出来破坏程序A的堆。或者考虑一下,如果程序A在程序A崩溃后继续运行该怎么办?)

您要做的是创建静态缓冲区。最简单的方法是制作.h文件:

/* my_buffer.h */
char bfr[HOWBIGISMYBUFFER];

然后包括你想要共享内存的任何地方。 会做的是写一个模块:

/* my_buffer.c */
char bfr[HOWBIGISMYBUFFER];

char * init(){ /* do your shm_open here and returna pointer to bfr */ }