如何在C中使用共享内存的两个不相关进程之间的指针共享一个结构?

时间:2014-02-17 13:41:07

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

我的结构如下:

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

我需要与另一个不相关的过程分享这个结构。我正在使用POSIX共享内存与shm_open()/ mmap()来实现这一点。但是,我的目标进程没有获得共享数据及其使用SIGSEGV,这很明显。如果有人帮助我,那将是很好的,特别是在共享内存(使用shm_open和mmap)的两个进程之间共享指针时会发生什么。

对于像

这样的结构
typedef struct shared_data_t
{
    char key[8];
    char message[32];
}shared_data;

一切正常!

2 个答案:

答案 0 :(得分:4)

shmat

       Using shmat() with shmaddr equal to NULL is the preferred, portable way
       of attaching a shared memory segment.  Be aware that the shared  memory
       segment  attached in this way may be attached at different addresses in
       different processes.  Therefore, any  pointers  maintained  within  the
       shared  memory must be made relative (typically to the starting address
       of the segment), rather than absolute.

答案 1 :(得分:3)

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

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

如果您只有一个密钥和一个要共享的消息,那么这样做的一种常见方法就是使用单个数据结构作为共享内存,正如您使用第二个ptrdiff_t定义所示: key和消息是struct的一部分,因此它们的偏移量是已知的,只是作为结构开头的偏移量。如果您要共享更复杂的数据,例如树或链接列表,则可能需要使用显式偏移。