【问题标题】:How to share a structure with pointers between two unrelated processes with shared memory in C?如何在 C 中使用共享内存的两个不相关进程之间的指针共享结构?
【发布时间】:2014-03-16 20:11:07
【问题描述】:

我的结构看起来像:

typedef struct shared_data_t
{
    char *key;
    char *message;
}shared_data;

我需要与另一个不相关的进程共享这个结构。我正在使用带有 shm_open()/mmap() 的 POSIX 共享内存来实现这一点。但是,我的目标进程没有获得共享数据并且它与 SIGSEGV 一起死亡,这是显而易见的。如果有人在这方面帮助我,那就太好了,特别是在使用共享内存(使用 shm_open 和 mmap)的两个进程之间共享指针时会发生什么。

对于像这样的结构,

typedef struct shared_data_t
{
    char key[8];
    char message[32];
}shared_data;

一切正常!

【问题讨论】:

  • 这很好用!您只是忘记了这个指针指向共享内存之外,因此另一个进程无法获取数据。但是您也可以在共享内存中分配“密钥”和“消息”。或者真的做一个没有指针的结构!
  • 这些指针引用的内存最好也共享,否则这有点毫无意义。
  • 使用从共享内存开始的偏移量而不是指针。
  • @Eddy_Em 感谢您的回复。我尝试将结构内容memcpy到共享内存中,但目标进程仍然没有得到它。我是否遗漏了一些非常明显的东西?

标签: c linux memory-management posix shared-memory


【解决方案1】:

shmat 的 Linux 手册页中有关于此的说明:

使用 shmat() 和 shmaddr 等于 NULL 是首选的可移植方式 附加共享内存段。注意共享内存 以这种方式附加的段可能附加在不同的地址 不同的过程。因此,在 共享内存必须是相对的(通常是相对于起始地址 段),而不是绝对的。

【讨论】:

  • 感谢您的回复。我正在使用 shm_open / mmap 方式为 IPC 使用共享内存。当然,我将 NULL 传递给 mmap 的第一个参数,让内核决定将内存段放置在哪里。
【解决方案2】:

该结构包含两个指针,用于keymessage。它们具有诸如 0x1000 和 0x1040 之类的值。您的第一个进程映射共享内存,例如地址 0x7000。它将结构复制到共享内存中。第二个进程映射相同的共享内存,比如地址 0x9000。它读取结构。然后它使用指针,这使它在地址 0x1000 和 0x1040 处查找 keymessage。但它们不在第二个进程的内存中的那些地址。所以第二个过程失败了。

要解决此问题,您必须将 keymessage 安排在共享内存中,并且您必须将它们安排在两个进程中的相同地址(通过告诉 mmap 您想要的确切位置映射内存,而不是让系统选择地址),或者您必须在共享内存中包含有关如何定位 keymessage 的信息。这通常通过使用偏移量而不是指针来完成。也就是说,不是在结构中具有指向char 的指针,而是具有偏移量(可能是ptrdiff_t 类型),它给出了从基本位置到键和消息的字节数。共享内存段的开头是一个典型的使用基础。

如果您只有一个键和一个消息要共享,那么执行此操作的常见方法是简单地为共享内存使用单个数据结构,正如您在 shared_data 的第二个定义中所示:键和消息是结构的一部分,因此它们的偏移量是已知的,只是从结构开始的偏移量。如果您要共享更复杂的数据,例如树或链表,那么您可能需要使用显式偏移量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 2013-05-07
    • 1970-01-01
    相关资源
    最近更新 更多