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

Sharing a struct with a pointer between two processes using `shm_open()`

我有以下结构,

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

其中*array指向动态分配的数组,maxmin保存数组中的最大和最小数。

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

我不知道它是否 更好 但你可以只用一次分配来做到这一点:分配一个大缓冲区以包含结构 数组,然后使 array 指向缓冲区 + 结构的大小。

好的,第一个答案就像你告诉医生 "It hurts when I do this" 而医生说 "then dont DO that!"

假设您打算这样做,请记住 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 是在别处定义的。尽管如此,你不想那样做。您想要实现的是一个可以共享的静态内存块,并且在堆上分配它会使您暴露于各种非常难以跟踪的错误。 (考虑,例如,您在程序 A 中分配内存,将其共享给程序 B,然后程序 B 通过缓冲区溢出破坏程序 A 的堆。或者考虑,如果程序 B 在程序 A 崩溃后保持 运行 怎么办? )

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

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

然后将其包含在您想要共享内存的任何位置。 I 会做的是写一个模块:

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

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

你需要这样做。

  1. 在每个进程中使用shm_open得到一个文件描述符。您必须在每个进程中传递 shm_open 相同的 name。名称是共享内存区域与其他共享内存区域的区别。名称必须以斜杠开头:"/somename".
  2. 使用第一步得到的文件描述符调用mmap.
  3. 来自 mmap 的地址 return 是您的共享内存地址。它是随机的,并且在每个过程中都是不同的。
  4. 因为3,你不能在共享内存区域内使用指针。您需要使用从共享内存开始的整数偏移量,或者完全取消间接寻址。例如,将整个共享内存区域视为一个整数数组。前两个单元格包含 minmax,实际数字从那之后开始。
  5. mmap 将 return 可用内存,您不需要静态或使用 malloc.
  6. 分配任何缓冲区