揮発性のメモ2

知識をメモ書きしておく

sem_init

共有メモリ上の名前なしセマフォを使ったプロセス間での排他制御

// gcc -Wall -lpthread test_seminit.c -lrt
// 動かんときは rm /dev/shm/hoge

#include <fcntl.h>      // O_CREAT
#include <semaphore.h>  // sem_wait
#include <stdio.h>      // printf
#include <unistd.h>     // sleep
#include <sys/mman.h>   // mmap
#include <stdlib.h>     // exit

#define die(msg) do{ perror(msg); exit(EXIT_FAILURE); }while(0)

int main()
{
    sem_t *sem;
    // まず共有メモリを普通にオープンし、
    int fd = shm_open("/hoge", O_RDWR, 0600);
    if(fd<0){
        // 共有メモリが無いときは新規に作成した上で
        fd = shm_open("/hoge", O_CREAT|O_EXCL|O_RDWR, 0600);
        if(fd<0) die("shm_open O_CREAT");
        // セマフォとして初期化をおこなう
        ftruncate(fd, sizeof(sem_t));
        sem = mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        // 1を指定するとバイナリセマフォになるよ
        sem_init(sem, 1, 1);
    }else{
        // 共有メモリ上のセマフォを参照する
        sem = mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    }

    printf("ロック\n");
    sem_wait(sem);

    printf("30秒スリープ\n");
    sleep(30);
    
    printf("アンロック\n");
    sem_post(sem);
    
    return 0;
}

Man page of SEM_INIT

  • 長所
    • 結構速い
    • 実は普通のopenで普通のファイルでも動く
  • 短所
    • 共有メモリを確保するのがだるい
      • セマフォが初期化されてるかどうかも意識しないといけない
      • すでにある共有メモリに間借りするとかでない限り避けたい
    • プログラムが途中で死ぬとロックがかかりっぱなしになる
    • 他言語と連携はできない