[C言語]共有メモリ(shm)を読み書きするサンプルコード



共有メモリとは

共有メモリはその名の通り、複数のプロセスで共有できるメモリである。
プロセス間通信(IPC)に利用される。
親プロセス、子プロセス、無関係なプロセス、どの関係であってもデータの共有が可能。

共有メモリの操作には下記のシステムコールを利用する。

システムコール 説明
shmget() 共有メモリ・セグメント識別子を獲得する
shmat() 自プロセスのデータセグメントにマップ(アタッチとも呼ぶ)する
shmdt() 共有メモリをアンマップ(デタッチとも呼ぶ)する
shmctl() 共有メモリをシステム上から削除する

サンプルプログラム

shm_receiver.c

shmを生成し、1秒置きに、shmの中身を画面に表示する。shmの中身が「end」になると、終了する。

#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strcpy */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main(void)
{
    int  id;
    char *adr;

    /* IPC_PRIVATEを指定すると、新規にshmが生成される。*/
    if((id = shmget(IPC_PRIVATE, 512, IPC_CREAT|0666)) == -1){
        perror("shmget");
        exit(-1);
    }

    printf("共有メモリID = %d\n",id);

    /* char形で取得 */
    if(( adr = (char *)shmat(id, NULL, 0)) == (void *)-1){
        perror("shmat");
    } else {
        strcpy(adr,"Initial");
        /* 1秒ごとに出力 */
        while(1){
            printf("%s\n",adr);
            /* 「end」で終了 */
            if (strcmp(adr, "end") == 0) {
                break;
            }
            sleep(1);
        }

        if(shmdt(adr)==-1){
            perror("shmdt");
        }
    }

    /* shmの破壊をする */
    if(shmctl(id, IPC_RMID, 0)==-1){
        perror("shmctl");
        exit(EXIT_FAILURE);
    }

    return 0;
}

shm_writer.c

コマンドラインから与えられた文字列をshmにコピーする。

#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strcpy */
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

int main(int argc, char *argv[])
{
    int   id;
    char  *adr;

    if( argc <= 2) {
        fprintf(stderr, "Usage: shm_writer shm_id string\n");
        exit(EXIT_FAILURE);
    }

    id = atoi(argv[1]);

    if(( adr = (char *)shmat(id,0,0)) == (void *)-1) {
        perror("shmat");
    } else {
        strcpy(adr, argv[2]);
        fprintf(stderr, "written.\n");
        if( shmdt(adr) == -1) {
            perror("shmdt");
        }
    }
}

実行例

$ gcc shm_receiver.c -o shm_receiver
$ gcc shm_writer.c -o shm_writer

$ shm_receiver
共有メモリID = 1234 ←IDを覚えておく
Initial

$ shm_writer 1234 hogehoge //shmに「hogehoge」を書き込む。
$ shm_writer 1234 end //shm_receverが終了する。

参考文献

詳解UNIXプログラミング
詳解UNIXプログラミング
例解UNIXプログラミング教室
例解UNIXプログラミング教室
C言語によるUNIXシステムプログラミング入門
C言語によるUNIXシステムプログラミング入門

参考URL

構築環境

FreeBSD 4.10-RELEASE

Comments are closed.