POSIX 共有メモリ・オブジェクト操作のメモ
Create:2004/03/24, update:2004/03/24
Semapho セマフォとは
セマフォ=共有メモリは、プロセス間でのメモリ共有を行う為の機能です。
この機能を使うことにより、スレッド操作で処理された結果の書き込みやデーモン化したプロセスの状態など色々な事に使用することができます。
と難しそうですが、共有メモリを操作する事自体は非常にシンプルで判りやすいと思います。
Manpage of SHM_OPEN RTCoreテクノロジーデモ 2003年12月18日 通信プリミティブ 2003年12月25日 分散プログラミングと同期
POSIX 共有メモリ・オブジェクト と 非POSIX 共有メモリ の違い
POSIXの 共有メモリは、スラッシュ (/) から始まる特殊なファイルデバイスとして作成されます。そのため shm_open の man を見ても判る通り open と同じファイルディスクリプタとして制御します。そのため通常ファイルとして参照することも可能です。
※共有メモリ・オブジェクトを指定するときも、名前(文字列)として指定
代わって、非POSIX 共有メモリは shmget 等のコマンドを使用し OS の管理化に置かれます。こちらは共有メモリを作成すると一意な番号が返されるため、その番号から共有メモリの先頭アドレスを取得し・・・。と操作します。
こんな感じに操作します
共有メモリ・オブジェクトの作成
共有メモリ・オブジェクトを作成するには、shm_open コマンドの O_CREAT | O_RDWR< を指定します。
作成できたら使用するメモリ領域の大きさを ftruncate コマンドで拡張します。
あとは、共有メモリ・オブジェクトの先頭アドレスをローカル変数に割り当てるだけです。
int main(int argc, char **argv) { int fd; int ret; char *addr; int i; char *walker; int fde, rete; char shm_object[1024]; sprintf(shm_object, "%s", argv[1]); fd = shm_open(shm_object, O_CREAT | O_RDWR, 0666); fde = errno; ret = ftruncate(fd, MMAP_SIZE); rete = errno; printf("fd = %d(%d), ret = %d(%d)\n", fd, fde, ret, rete ); addr = mmap(0, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { exit(1); } walker = (char *)addr; for (i = 0; i < MMAP_SIZE/sizeof(char); i++) { *walker = 'M'; walker++; } }
※ 'M' という文字を共有メモリ全てに埋め込んでます(笑)。
共有メモリ・オブジェクトの読込み
共有メモリ・オブジェクトを参照するには、shm_open コマンドの O_RDWR を指定します。
あとは、共有メモリ・オブジェクトの先頭アドレスをローカル変数に割り当てるだけです。
fd = shm_open(shm_object, O_RDWR, 0666); addr = mmap(0, MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { exit(1); } walker = (char *)addr; hoge_s = (Hoge_s *)addr; for (i = 0; i < MMAP_SIZE/sizeof(char); i++) { printf("i = %d, %c\n", i, *walker); walker++; }
※ hoge_s = (Hoge_s *)addr の様に、構造体のアドレスに設定しブロック単位に処理するというのも手です(笑)。
共有メモリ・オブジェクトの削除
共有メモリ・オブジェクトを削除するには、shm_unlink コマンドに共有メモリ・オブジェクトを指定するだけです。(これだけっす)
ret = shm_unlink(shm_object);
※ 簡単でしょ?
各サンプルプログラム
特殊なライブラリは、つかってないので gcc, cc でもコンパイルできるでしょう。
共有メモリ・オブジェクトの作成 共有メモリ・オブジェクトの読込み 共有メモリ・オブジェクトの削除