共有メモリの使い方


0.はじめに

複数のプロセスが走って、そこでのパラメータを共有したいとき、 共有メモリを使うのが一番手っ取り早いでしょう。 プロセス間通信よりも簡単でしょう。 違うマシンだったら通信しなけりゃいけないでしょうけど。

0.5. サンプルプログラム

sample program(tar.gz) ←これを見ると早いのではないでしょうか。 もちろん、manも大いに活用してください。

web上でみたい方はこちらへ。 sample program

1.メモリを確保する

メモリを共有するためには、中心となるプログラム名(KEYFILE_PATH)と 暗証番号(PROJ_CHAR)を決めておきます. これを利用して、keyを作成します。

  /* 今後はkeyを使う */
  key = ftok(KEYFILE_PATH,PROJ_CHAR);

そして、それを使ってメモリを確保します.

shm_initialize(key, sizeof(struct SHM_PARAM), &shd_param_id, (int *)&param_ptr);
param_ptr->shd_param_id = shd_param_id;
int shm_initialize(key_t shm_key, int shm_size,int *shrd_id,int *shm_ptr)
{
  /* idを取得する */
  *shrd_id = shmget(shm_key, shm_size, IPC_CREAT|0666);
  if( *shrd_id < 0 ){
    printf("[shm_initialize]: Can't Access to the Shared Memory !! \n" );
    return -1;
  }

  /* 共有メモリのアドレスを取得する */
  *shm_ptr = (int)shmat( *shrd_id, NULL, 0);

  /* 共有メモリを0で初期化 */
  memset( (void *)*shm_ptr, 0, shm_size );

  return  *shrd_id;
}

2.共有する

すでにメモリを確保したプロセスは、 共有メモリの場所がどこにあるのか知っているのですから, これ以上必要な手順はありません. しかし, これから走り出すプロセスは、 どこにメモリがあるかなんてしりません。

なので、これから共有メモリのアドレスを取得しなければなりません。 方法は上とほとんど同じ。

shm_access(key, sizeof(struct SHM_PARAM), &shd_param_id, (int *)&param_ptr);
param_ptr->shd_param_id = shd_param_id;
int shm_access(key_t shm_key, int shm_size, int *shrd_id, int *shm_ptr)
{
  *shrd_id = shmget(shm_key, shm_size, 0444);
  if( *shrd_id < 0 ){
    printf("Can't Access to the Shared Memory !! \n" );
    return(-1);
  }
  *shm_ptr = (int)shmat( *shrd_id, (const void *)NULL, 0);
  
  return *shrd_id;
}

これで、param_ptrが共有メモリと関係付けられました。あとはこれを使ってい きましょう。

3.アクセスする

param_ptr->a を普通に使うことができるようになる。

ただ、ここで問題なのは、競合が起きてしまうということ。 これの対処方法は、そのうち考えるとしましょう。 まあ、とにかく動かせるようになったということでよしとしましょう。

3.メモリを解放する

メモリを確保したら、使い終わったあとに解放するのがマナーですね。 ということで、解放しましょう。

erase_shm(param_ptr);
int erase_shm(struct SHM_PARAM *param_ptr)
{
    shmctl(param_ptr->shd_param_id, IPC_RMID, 0);

    return(0);
}


参考にしたページ
  • プロセス間通信(System V IPC)プログラミング登竜門