2017-10-15 34 views
1

フォーク後または子プロセスで共有メモリを作成する方法は?フォーク後または子プロセスで共有メモリを作成するにはどうすればよいですか?

共有メモリにグローバルポインタを作成してから、子プロセスで複数のノードを動的に作成し、このグローバルポインタにノードを追加します。

#include <string.h> 
#include <unistd.h> 

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 

struct shm_t { 
     int data; 
     struct shm_t *next; 
}; 

void main() { 
     struct shm_t *shm = (struct shm_t *)mmap(NULL, sizeof(*shm), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0); 

     shm->data = 1; 
     shm->next = NULL; 

     int pid = fork(); 

     if (pid == 0) { 
       printf("Child \n"); 
       // How to create a shared shm_t here, and assign to *shm->next? 
     } else { 
       printf("Parent \n"); 
     } 
} 
+2

このような小さなチャンクに共有メモリを割り当てることは非常に効率が悪く、すばやく使い果たします。 –

+1

あなたは必要以上の量を割り当てるのが最良です。あなた自身のアロケータ/デアロケータを実装してください(自由にするために 'MADV_DONTNEED'を使用します)。 – o11c

+0

@イグナシオはこれを達成することは可能でしょうか? – vego

答えて

1

2つのプロセスがメモリを共有するためには、共通のものが必要です。

最初の割り当ては、MAP_SHAREDで割り当てられているため共有され、子プロセスは親から継承します。フォークがすでに終了していれば、それが自動的に起こる方法はありません(ただ一つの例:子供がこれを共有するプロセス?親は、Linuxに関しては特別な意味を持たないランダムなプロセスです)。

これを正しく行う方法は、ファイル記述子を共有することです。しかし、ここの落とし穴の数は驚異的です。

のは、最初のソリューションで始まり、その後、それは動作しません理由を理解してみましょう:

// Before the fork 
int shared_fd = open("/dev/shm/somefile", O_CREAT|O_TRUNC|O_EXCL|O_RDWR, 0600); 
// Check for errors 
unlink("/dev/shm/somefile"); 
// check for errors 

// Now you can fork 

あなたは今、(すなわちプロセス間でそれを共有することが可能であり、このファイルからmmapを使用している場合 - 1プロセスの書き込みは他のプロセスに表示されます)。

  • ファイルが空で作成され、ファイルの末尾過去mmapことはできません:私が言ったように

    は、ここに落とし穴の数は巨大です。これを有効にするには、ftruncateを使用してファイルを増やす必要があります。しかし、これは問題です。 ftruncateへの呼び出しを同期する必要があります。そうしないと、両方のプロセスが同じサイズのファイルを増やしていると思われる更新プログラムの問題が発生します。

  • まだは、メモリ内にポインタを格納できません。その理由は、メモリが共有されているということです。つまり、あるプロセスの書き込みは、他のプロセスの書き込みがすぐに見えるからです。ただし、同じアドレスにマップされるという保証はありません。

私はあなたがここで何をしたいのか分かりません(2つのプロセス間でリンクされたリストを共有したい場合は、ここで処理するために大きな同期の問題があります)。あなたが必要とするメモリの量を事前に制限することができれば、元のmmapであらかじめ割り当てておくだけです。

ただし、ここで達成しようとしていることは、達成しようとしている方法では不可能です(穏やかではありません)。

関連する問題