大量のデータをメッセージで送るのは効率的ではありません。同じ計算機の 上にあるプロセス同士は共有メモリーを使って情報の交換が可能です。共有メ モリーはそれぞれのプロセスのメモリー空間に割り当てられ、随意にアクセス が出来ます。しかし相手のプロセスが書き換えたことはまったくわかりません。 メモリー上の首尾一貫性をたもつにはセマフォやロックなどの排他制御が必要 になります。
共有メモリーもIPCの一部として実装されています。shmgetコールで共有メ モリー識別子を確保して、shmatコールで実際にメモリーがマップされ共有メ モリーへのポインターを入手します。shmdtでマップを解除し、shmctlで共有 メモリー識別子を削除します。次の例を見てください。
#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #define KEY 12345 int shmid; char *shmp; /* KEY(12345)をキーとして65536(0x10000)バイトの共有メモリーを 新規に準備し、オーナのみにアクセスを許す。*/ shmid = shmget( KEY, 0x10000, IPC_CREAT | 0600 ); if( shmid == -1 ) { /*戻り値が-1の時は失敗*/ } /* 共有メモリーの先頭をオプション無しで確保*/ shmp = shmat( shmid, 0, 0 ); /*これでshmpがさすメモリーは他のプロセスと共有*/ ... shmdt( shmp ); /* 共有メモリーを切り離す*/ shmctl( shmid, IPC_RMID, 0 ); /* 共有メモリー識別子を削除 */
一旦共有メモリーが確保されると後は単にポインターとして参照が可能にな ります。sh mctlは共有メモリーの状態を調べたり、UIDなどを設定するのにも 使われます。
共有メモリーもIPCの一部ですからipcsやいpcrmコマンドが使えます。共有 メモリーを指定するオプションは-mです。ipcs -mとやるとメモリーだけ見え ます。
共有メモリーを扱うときに注意して欲しいことがあります。共有メモリーを 参照するポインターはそのプロセスの仮想メモリー空間での値(例えば100)を 持っています。別のプロセスでは同じ共有メモリーを指すのに異なった値(例 えば200)を持つことになります。仮想メモリー空間での配置が異なれば当然こ ういうことになります。つまりポインターは単一のプロセスの中だけで意味が あるということです。共有メモリーのなかの位置(例えば先頭から20バイト目) を表すのに共有メモリー上にポインターを置いても(例では100の20先だから 120)、それは正しく働かないことになります。別のプロセスから見ると(220が 正しい値なのに120をもらってしまう。)全然意味のないところを指しているか らです。共有メモリーに置いて意味のある位置データは、その目的のデータが 共有メモリーの先頭から何ワード目か(今の例では20バイト目)ということです。 それぞれのプロセスは自分の共有メモリーへのポインターにこの値を足して目 的のデータを参照することがはじめて出来るわけです。