The BAQ/Memo/Linux C/Semaphoreとunion semun

Japanese English
Nuclear Physics Data Acquisition Orchestra Gallery Memo Diary Link Home
Linux C Fortran Postscript Home

もどる

Semaphoreを使うときには、semctlを使ってSemaphoreの制御操作を行う。
semctlではunion semunを使うが、これがちょいとくせ者である。

Linux Programmer's Manualによると

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* 共用体 semun の定義は <sys/sem.h> に含まれている */
#else
/* X/OPEN に従うならば自分自身で以下のように定義しなければならない */
union semun {
     int val;                    /* value for SETVAL */
     struct semid_ds *buf;       /* buffer for IPC_STAT, IPC_SET */
     unsigned short int *array;  /* array for GETALL, SETALL */
     struct seminfo *__buf;      /* buffer for IPC_INFO */
};
#endif

int  semctl  (int  semid, int semnum, int cmd, union semun
arg)

と書いてある。
つまり 「__GNU_LIBRARY__」が定義してあって、「_SEM_SEMUN_UNDEFINED」が定義して無い場合はsemun の定義は <sys/sem.h>に書かれていて、そうでない場合は自分で union semun を定義しなさいと言っている。
どうやらKernelが2.0系だとsemunは<sys/sem.h>に定義してあって、 2.2系では自分で定義しなければならないようである。
これを知らないとSemaphoreを使うときに悩まされる。

<bits/sem.h>によると

/* The user should define a union like the following to use it for arguments
   for `semctl'.

   union semun
   {
     int val;                           <= value for SETVAL
     struct semid_ds *buf;              <= buffer for IPC_STAT & IPC_SET
     unsigned short int *array;         <= array for GETALL & SETALL
     struct seminfo *__buf;             <= buffer for IPC_INFO
   };

   Previous versions of this file used to define this union but this is
   incorrect.  One can test the macro _SEM_SEMUN_UNDEFINED to see whether
   one must define the union or not.  */
#define _SEM_SEMUN_UNDEFINED    1

と書いてある。
「前のバージョンではこのファイルでunion semunを定義してたけれども、これは正しくない。「_SEM_SEMUN_UNDEFINED」を使ってこのunionが定義されているか否かを調べることができる。」
だそうです。

Last Update: 2005/3/4
Hidetada Baba
baba rarfaxp.riken.jp