2011-02-23 15 views
1

私はLinux 2.6で、奇妙な問題があります。私は、プロセスごとに1つの異なる3つの共有メモリセグメントを取得する必要がある3つの同時プロセス(同じプロセスから分岐)を持っています。プロセスの各、このコードを実行する(「メッセージ」タイプがユーザー定義であることに注意してください)プロセスがshm_open()を使用するとき、Linuxカーネルはどのようにメモリポインタを割り当てますか?

message *m; 
    int fd = shm_open("message", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); 
    ftruncate(fd, sizeof(message)); 
    m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 
    char messagename[16]; 
    snprintf(messagename, sizeof(messagename), "%p", m); 
    char path[32] = "/dev/shm/"; 
    strcat(path, messagename); 
    rename("/dev/shm/message", path); 

は私が少し説明しましょう:私は、すべてのプロセスがメッセージを含む共有メモリ領域を割り当てたいです。別のプロセス(メッセージ受信者)が同じshmにアクセスできるようにするために、私はshmファイルの名前を "message"から、メッセージポインタの後に付けられた文字列に変更します(これはメッセージを受け取るプロセスがすでにポインタを知っているからです)。

shm_openで得られたfdをmmappingするときに、すべてのプロセスが受け取ったポインタを(デバッグ目的のために)印刷しようとしましたが、すべてがSAMEポインタを持っていることに気付きました。どのように可能ですか?私は他のプロセスがshm_open()を実行した後で、セグメントの名前を変更する前にshm_open()を実行したと思っていたので、これらのコード行をプロセス共有mutexを使ってアトミック操作にしようとしました。

本当にありがとうございました。

答えて

2

プロセスはすべて、フォークの瞬間に同一のアドレス空間レイアウトで開始され、その後非常に似たコードパスが続きました。したがって、それらが全て同じ値のmで終わるのは驚くべきことではありません。彼らは独立したプロセスになったら

はしかし、彼らのアドレス空間はとてもmの同じm Sの全てが同じものを指していることを意味するものではない持つ、独立しました。

さらに、共有メモリブロックの作成後に/dev/shmエントリの名前を変更する考えは、安全で移植性が高いとは確信していません。各プロセスの共有メモリブロックに一意の名前を付ける場合は、プロセスID(特定の時点で一意であることが保証されている)に名前を付け、shm_openに直接渡すのではなく、後で名前を変更するのか?

+0

おかげさまで、あなたのアイデアpidを使用するのは良いようだと私は確かにそのショットを与えるだろう。しかし、shm_open()を使って私は共有メモリ(とプライベートではない)メモリポインタを尋ねました。共有メモリに関しては、私が考えていたプロセスの仮想メモリ空​​間にかかわらず、いつも別のポインタを期待していました。 さらに、プロセスによって呼び出されるshm_open()のそれぞれに異なる名前を使用しても、それらはすべて同じアドレスを取得します。 shm_open()+ mmap()が共有メモリポインタを与える場合、shmの名前が異なる場合、どのようにして同じものになりますか? –

+2

プロセスからのメモリへのすべてのアクセスは、そのプロセスの仮想アドレス空間を経由します。基礎となるメモリは共有することができますが、各アプリケーションのビューはプライベートです。したがって、OSの裁量により、各プロセスの同じアドレス、または異なるプロセスの異なるアドレスに表示される可能性があります。 – mhsmith

+1

...逆に、異なるプロセスの同じアドレスに異なる共有メモリブロックが現れることがあります。これがあなたに起こります。 – mhsmith

1

異なるプロセス内の同じ仮想アドレスは、メモリ内の異なる物理ページにマップできます(通常は実行します)。 the wikipedia article on virtual memoryと読んでみてください。

+0

ありがとうございます!私はすでに仮想メモリについて知っています。しかし、プロセスが異なるメモリ空間を持っていても、shm_open()とmmap()を使うと、毎回 "一意"になるべき共有ゾーンへのポインタが返されると私は考えていました。 –

0

フォークする前にmmapを作成するだけで同様の問題を解決しました。したがって、フォーク後、同じ領域がすべてのプロセス間で共有されます。私は定義された位置に私のセマフォとmutexesを置く。それは完全に動作します。

関連する問題