1.shmget関数でキ-を指定して共有メモリを作成する方法
○共有メモリとは
共有メモリとは、複数のプログラムのコ-ドで共有して使用することの出来るデ-タ領域である。共有メモリを使用することによって値を共有することが本来困難な場合にあたって広い範囲で値を共有することができる。
○共有メモリの作成について
まず、基本的な共有メモリの作成方法については以下のサイトに分かりやすい説明があるので参考にすると良い。
上記のサイトを用いて共有メモリを作成して動かすこと自体はできたのだが、サイトの内容を応用して作ろうとしたのだが、shmget関数の使用するにおいて以下の点で行き詰まった。
- ・メモリサイズの指定の仕方が分からない
- ・共有メモリのキ-の指定の方法が分からない
2.shmget関数内のメモリサイズの設定について
1まず、メモリサイズの単位はバイトとなる。表記の仕方に関しては10進数でも、16進数数表記のどちらでもよい。
例えば、32バイトの共有メモリを作成したい場合は以下のように記載すれば良い
shmget("第一引数",32)
また、参考までに、C言語でよく使用される型のサイズを挙げておくと以下のようになる。
- ・int型……4バイト
- ・char型……1バイト
3.shmget関数のキ-の指定について
共有メモリをキ-を指定して作るには以下のように書けば良い
(例では、数字を999にしているが実際に書く場合には既存のキ-と被っていなければなんでもいい)
shmget(999,"第二引数",IPC_CREAT | IPC_EXCL)
第一引数……指定するキ-を書く
IPC_CREAT……新しいキ-を作成
IPC_EXCL……キ-が重複していたら失敗させる
なお、上記のリンク先に書いてあるソ-スを下記の条件で書き換えると以下のようになる。
- 確保するメモリサイズを32バイトにする
- メモリキ-を1000に設定する
- 実行してから3つ目のprintfを画面表示は20秒待ってから行われるように変更
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <unistd.h>
#include <wait.h>
enum { SEGMENT_SIZE = 32 };
const char *data = "Hello there!";
int main() {
int status;
int segment_id;
segment_id = shmget(1000, SEGMENT_SIZE,
IPC_CREAT | IPC_EXCL);
char *sh_mem = (char *)shmat(segment_id, NULL, 0);
printf("Segment ID %d\\n", segment_id);
printf("Attached at %p\\n", sh_mem);
sleep(20);
memmove(sh_mem, data, strlen(data) + 1);
printf("%s\\n", sh_mem);
shmdt(sh_mem);
shmctl(segment_id, IPC_RMID, 0);
exit(EXIT_SUCCESS);
}
4.共有メモリのキ-の確認について
上記の共有メモリの作成しただけではキ-を確認することができない。そのため、キ-を確認をするためにはプログラムを動いている最中に共有メモリを確認するための以下のコマンドを入力する必要がある。
ipcs
なお、コマンドを入力すると以下のように出力される。
※上記のサンプルコードに待つ処理を追加したのはこのため
詳しい内容については以下のサイトに分かりやすい説明があったので、参考にするとよい
ここでipcsコマンド入力の出力結果を見ると10進数で書かれてあるshmidはshmget関数の返り値が反映されており、これはshmget関数の引数で指定した値とは異なっている……という人が大半であると思う。
一見違和感があるが、実はこれは正常であり、問題ない。
というのも、shmget関数の第一引数で記載したものは16進数に変換されてキーの列に反映されている。
pcにおいて0xの後に続いている数字(と文字abcdef)は16進数と決まっているのでその部分について以下のサイトで調べればよい。