UNP(卷2:進程間通信)—— 第11章:System V 信號量

先前介紹的POSIX信號量概念:

  • 二值信號量:0,1
  • 計數信號量:0和某個限制值之間的信號量。

System V 中信號量:

計數信號量集:一個或多個信號量,其中每個都是計數信號量。

對於系統的每個信號量集,內核維護一個信息結構:<sys/sem.h>中定義

/* Data structure describing a set of semaphores.  */
struct semid_ds
{
  struct ipc_perm sem_perm;            /* operation permission struct */
  __time_t sem_otime;                  /* last semop() time */
  __syscall_ulong_t __glibc_reserved1;
  __time_t sem_ctime;                  /* last time changed by semctl() */
  __syscall_ulong_t __glibc_reserved2;
  __syscall_ulong_t sem_nsems;         /* number of semaphores in set */
  __syscall_ulong_t __glibc_reserved3;
  __syscall_ulong_t __glibc_reserved4;
};


semget、semop、semctl

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

int semget(key_t key, int nsems, int semflg);
                                                      // 返回:若成功返回非負標識符,出錯爲-1

int semop(int semid, struct sembuf *sops, size_t nsops);
                                                      // 返回:若成功返回0,出錯爲-1

int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout);

int semctl(int semid, int semnum, int cmd, ...);
                                                      // 返回:成功返回非負值,出錯-1

semget 函數:創建一個信號量集,或者訪問一個已存在的信號量集。

  • 返回值:一個稱爲信號量標識符的整數。
  • nsems參數:指定集合中的信號量數。若不創建,只訪問一個信號量集,可以設置爲0。一旦創建,就不能改變其中的信號量數。
  • semflg:SEM_R 和SEM_A的組合。R表示read。A表示alter。還可以與IPC_CREAT、IPC_EXCL按位與。

當創建一個信號量集時,semid_ds結構中的以下成員被初始化:

  • sem_perm 結構中的uid 和 cuid 成員被置爲調用進程的有效用戶ID,gid 和 cgid 成員被置爲調用進程的有效組ID。
  • semflg參數中的讀寫權限位存入sem_perm.mode。
  • sem_otime被置爲0,sem_ctime則被置爲當前時間。
  • sem_nsems被置爲nsems參數的值。
  • 與該集合中每個信號量關聯的各個sem結構並不初始化。這些結構是在以SET_VAL或SETALL命令調用semctl時初始化的。

semop 函數:打開後,對其中一個或者多個信號量的操作。

其中sembuf結構:

/* Structure used for argument to `semop' to describe operations.  */
struct sembuf
{
   unsigned short int sem_num;   /* semaphore number (0,1,...,nsems-1) */
   short int sem_op;             /* semaphore operation */
   short int sem_flg;            /* operation flag ( 0, IPC_NOWAIT, SEM_UNDO ) */
};

/* Flags for `semop'.  */
#define SEM_UNDO    0x1000      /* undo the operation on exit */

sem_op:正數,0,負數


semctl 函數:對一個信號量執行各種控制操作。

semnum參數:信號量成員。僅僅用於GETVAL、SETVAL、GETNCNT、GETZCNT、GETPID命令。

第四個參數是可選的,取決於第三個參數cmd。

注意:這個聯合需要應用自己定義,它是按值傳遞的,不是按引用傳遞的。

/* Commands for `semctl'.  */
#define GETPID      11      /* get sempid */
#define GETVAL      12      /* get semval */
#define GETALL      13      /* get all semval's */
#define GETNCNT      14      /* get semncnt */
#define GETZCNT      15      /* get semzcnt */
#define SETVAL      16      /* set semval */
#define SETALL      17      /* set all semval's */

/* Control commands for `msgctl', `semctl', and `shmctl'.  */
#define IPC_RMID    0       /* Remove identifier.  */
#define IPC_SET     1       /* Set `ipc_perm' options.  */
#define IPC_STAT    2       /* Get `ipc_perm' options.  */

union semun {
   int              val;    /* Value for SETVAL */
   struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
   unsigned short  *array;  /* Array for GETALL, SETALL */
   struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */
};

struct  seminfo
{
  int semmap;
  int semmni;
  int semmns;
  int semmnu;
  int semmsl;
  int semopm;
  int semume;
  int semusz;
  int semvmx;
  int semaem;
};
GETVAL ---把semval的當前值作爲函數返回值返回。既然信號量絕不會是負數(semval被聲明成一個整數unsigned short),那麼成功的返回值總是非負數。

SETVAL ---把semval值設置成爲arg.val。如果操作成功,那麼相應信號量在所有進程中的信號量調整值(semadj)將被置爲0。

GETPID ---把sempid的當前值作爲函數返回值返回。

GETNCNT---把semncnt的當前值作爲函數返回值返回。

GETZCNT---把semzcnt的當前值作爲函數返回值返回。

GETALL----返回所指定信號量集內每個成員的semval值。這些值通過arg.array指針返回,函數本身的返回值則爲0。注意,調用者必須分配一個unsigned short整數數組,該數組要足夠容納所指定信號量集內所有成員的semval值,然後把arg.array設置成指向這個數組。

SETALL----設置所指定信號量集中每個成員的semval值。這些值是通過arg.array指針指定的。

IPC_RMID--把由semid指定的信號量集從系統中刪除掉。

IPC_SET---設置所指定信號量集的semid_ds結構中的以下三個成員:sem_perm.uid、sem_perm.gid和sem_perm.mode,這些值來自由arg.buf參數指向的結構中的相應成員。semid_ds結構中的sem_ctime成員也被設置成當前時間。

IPC_STAT--(通過arg.buf參數)返回所指定信號量集當前的semid_ds結構。注意,調用者必須首先分配一個semid_ds結構,並把arg.buf設置成指向這個結構。


信號量限制:




















發佈了98 篇原創文章 · 獲贊 74 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章