我的结构如下:
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;
一切正常!
答案 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)
结构包含两个指针,分别用于key
和message
。它们具有诸如0x1000和0x1040之类的值。您的第一个进程映射共享内存,例如地址0x7000。它将结构复制到共享内存中。第二个进程映射相同的共享内存,例如地址0x9000。它读取结构。然后它使用指针,使其在地址0x1000和0x1040处查找key
和message
。但是他们不在第二个过程的记忆中。所以第二个过程失败了。
要解决此问题,您必须安排key
和message
位于共享内存中,并且您必须安排它们在两个进程中处于同一地址(通过告知{{1}你想要映射内存的确切位置,不要让系统选择地址),或者你必须在共享内存中包含有关如何找到mmap
和key
的信息。这通常通过使用偏移而不是指针来完成。也就是说,不是在结构中有指向message
的指针,而是具有偏移量(可能具有类型char
),其给出从基本位置到密钥和消息的字节数。共享内存段的开头是一个典型的使用基础。
如果您只有一个密钥和一个要共享的消息,那么这样做的一种常见方法就是使用单个数据结构作为共享内存,正如您使用第二个ptrdiff_t
定义所示: key和消息是struct的一部分,因此它们的偏移量是已知的,只是作为结构开头的偏移量。如果您要共享更复杂的数据,例如树或链接列表,则可能需要使用显式偏移。