如何在2个进程之间分配system-V共享内存

时间:2016-11-20 03:44:47

标签: c linux shared-memory

最近,我尝试在2个进程(host& guest)之间创建shared_memory, 并且在此内存中分配名为my_shared的结构。 但结构有一个指针int *,我需要指出一个 他的一部分记忆,这是我的代码:

shared.h

#define KEY 5114
struct my_shared{
    int *a;
    int b;
};
void *mem;

host.c

#include <...>
#include "shared.h"

struct my_shared *st;

int main(void)
{
    int id;
    key_t key = KEY;

    id = shmget(key, 1024, 0666|IPC_CREAT|IPC_EXCL);//1K shared memory
    if(id < 0){/* do error handle */}

    mem = shmat(id, (void *)0, 0);
    if(mem == MAP_FAILED){/* do error handle */}

    //point out the shared memory base address
    st = (struct my_shared *)mem;
    //point out the int *a memory address
    st->a = (int *)(mem + sizeof(struct my_shared));

    //read-write the memory
    int i = 0;
    do{
       st->b = i++;
       *(st->a) = ++i;
       printf("a = %d, b = %d\n", st->b, *(st->a));
       sleep(1);
    }while(1);

    shmdt(st);
    return 0;
}

guest.c

#include <...>
#include "shared.h"

struct my_shared *st;

int main(void)
{
    int id;
    key_t key = KEY;

    id = shmget(key, 1024, 0); //1K shared memory
    if(id < 0){/* do error handle */}

    mem = shmat(id, (void *)0, 0);
    if(mem == MAP_FAILED){/* do error handle */}

    //point out the shared memory base address
    st = (struct my_shared *)mem;
    //point out the int *a memory address
    st->a = (int *)(mem + sizeof(struct my_shared));

    //read the memory
    do{
       printf("a = %d, b = %d\n", st->b, *(st->a));
       sleep(3);
    }while(1);

    shmdt(st);
    return 0;
}

如果只执行host,但执行guest时,*(st-> b)会导致host粉碎,gdb说*(st-&gt; a )无法访问host

如果我修改了代码,让hostguest只访问st-&gt; b,它的工作正常!

为什么访问*(st-&gt; a)会粉碎?我丢了什么东西吗?

我的环境是ubuntu 14.04LTS和gcc4.8.5

1 个答案:

答案 0 :(得分:0)

在共享内存中传递指针无法正常工作,因为该块通常位于每个进程的不同地址中。

但是有一个解决方案:传递指针本身和指向共享块的指针之间的差异。这样,客户端只需将其基地址添加到内部值,并具有指向数据的有效指针。当然,服务器中的指针必须指向同一共享内存块中的区域。