2016-11-20 10 views
0

最近、2つのプロセス(ホスト&ゲスト)、 とmy_sharedという名前の構造体をこのメモリに割り当てる間にshared_memoryを作成しようとしました。 しかし、構造体ポインタint *を持って、私は彼に、メモリの 一部を指摘する必要があり、ここに私のコードは次のとおりです。2つのプロセス間でsystem-V共有メモリを割り当てる方法

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-> a)のhostのためにアクセスすることはできません、

場合コードを変更すると、hostguestはst-> bにしかアクセスできません。

なぜアクセス*(st-> a)がクラッシュするのですか?私は何かを失った?

私のenvがブロックは通常、各プロセスの異なる住所に位置しているので、動作しないことができる共有メモリ内のポインタを渡すgcc4.8.5

+0

あなたは 'host'と' guest'の両方で 'st-> a 'の値を変更しています。つまり、彼らはある時点で 'st-> a'の間違った値を見ることになります。少なくとも一つのプロセスで共有 'st-> a '値を変更してはいけません。 – kaylum

+0

返信用のthxですが、私は 'ホスト'の 'st-> a'値を変更するだけです、' guest'は 'st-> a'の値を読みますか? –

+0

本当ですか? guest.cに 'st-> a'(int *)(mem + sizeof(struct my_shared));と'あなたがゲストに 'st-> a'を設定していなければそれを逆参照してはいけません。他のプロセスによって設定されている場合、その値は無効です。 – kaylum

答えて

0

でのUbuntu 14.04LTSです。

しかし、解決策があります:ポインタ自体とポインタへのポインタを共有ブロックに渡します。このようにして、クライアントはその内部アドレスに基本アドレスを追加し、データへの有効なポインタを持ちます。もちろん、サーバ内のポインタは同じ共有メモリブロック内のゾーンを指していなければなりません。

関連する問題