共有メモリ
共有メモリもセマフォと同じ雰囲気で取得,設定,操作する.
共有メモリに関する関数を以下に示す.
- int shmget(key_t key, int size, int shmflg);
- 共有メモリを作成する.shmflgでパーミッションなどの設定をする.
- void *shmat(int shmid, const void *shmaddr, int shmflg);
- 共有メモリにアタッチする.shmidはshmgetの返り値で,共有メモリはのポインタを返す.shmaddrは共有メモリのアドレスに関係するようだが,0にしとけばシステムがよきにはからう.
- int shmdt(const void *shmaddr);
- 共有メモリからデタッチする.shmaddrはshmatによって返される共有メモリへのポインタ.
- int shmctl(int shmid, int cmd, struct shmid_ds *buf);
- 共有メモリを制御する.cmdで指定することでいろんなことができるようだが,これにIPC_RMIDを指定すると共有メモリを削除する.
- shmgetで共有メモリを作成
- shmatで共有メモリにアタッチ
- アタッチした共有メモリ上のデータは普通に扱える(ただし同期には注意).
- shmdtで共有メモリからデタッチ
- shmctlで共有メモリを削除
共有メモリを使用するサンプルを以下に示す.このサンプルではセマフォで同期をとりつつ共有メモリにアクセスする.
以下同期をセマフォで取ったとき(gcc -DSYNC shared-memory.c)の実行結果.
1303: ****** (6) 1304: ***** (5) 1303: ****** (6) 1304: ***** (5) 1303: ****** (6) 1303: ******* (7) 1304: ****** (6) 1304: ***** (5) 1303: ****** (6) 1304: ***** (5) 1303: ****** (6) 1304: ***** (5) 1303: ****** (6) 1303: ******* (7) 1304: ****** (6) 1303: ******* (7) 1303: ******** (8) 1304: ******* (7) 1303: ******** (8) 1304: ******* (7) 1303: ******** (8) 1304: ******* (7) 1304: ****** (6) 1303: ******* (7) 1304: ****** (6) 1303: ******* (7) 1303: ******** (8) 1303: ********* (9) 1304: ******** (8) 1304: ******* (7) 1303: ******** (8) 1304: ******* (7) 1303: ******** (8) 1303: ********* (9) 1303: ********** (10)各行が前後の行と1ずつずれているのでうまくいっているはず.以下は同期を取らない場合(gcc shared-memory.c)の実行結果(一部).
1483: ****** (6) 1483: ***** (5) 1482: ****** (6) 1483: ***** (5) 1482: ****** (6) 1483: ***** (5) 1483: **** (4) 1482: **** (4) 1483: **** (4) 1482: ***** (5) 1483: **** (4) 1483: *** (3) 1482: *** (3) 1483: *** (3) 1482: *** (3) 1482: **** (4)このようにたまに増減がないパターンができる(上では4や3が連続している).これは同期がとれていればあり得ない.

