本文给出创建信号量涉及到的函数API,每个函数都给出超链接,若本文的内容不够清晰,直接点击链接查看原文。

1. 创建一个信号量

使用semget函数创建/打开一个信号量集,

#include <sys/sem.h>

// get a System V semaphore set identifier
int semget(key_t key, int nsems, int semflg);

参数:

  • key,进程间通信(IPC)键,类型为key_t,实为长整型(在sys/types.h中被定义)
  • nsems,信号量集(union semun)中信号量的个数
  • semflg,如IPC_CREAT | 0660。指定IPC_CREAT,若信号集不存在,则创建一个

返回值:

  • on success: the id of a semaphore set (semaphore set IPC identifier)
  • on error: -1

1.1 进程间通信键

有两种方法可以标识进程间通信(inter-process communication,IPC)的对象,两者一一对应

  • 内部名:标识符ID(identifier),类似于文件描述符,semget返回的就是标识符
  • 外部名:键key,类似于文件名

可能通过ftok函数创建一个IPC键,

#include <sys/ipc.h>

// convert a pathname and a project identifier to a System V IPC key
key_t ftok(const char *pathname, int proj_id);

参数:

  • pathname: an existing, accessible file

  • proj_id: must be nonzero

2. 初始化信号量

semget创建一个信号集并没有对其初始化,需要对其初始化,比如锁初始时是开的还是关的。信号量集的定义如下:

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 */
};

使用函数semctl对信号量进行初始化,

#include <sys/sem.h>

// System V semaphore control operations
int semctl(int semid, int semnum, int cmd, ...);

参数:

  • semid: 信号量集的标识符

  • semnum: [0, nsems-1]

  • cmd: 操作命令

    • SETVAL, Set the value of semaphore number semnum to arg.val

    • IPC_INFO, GETVAL, …

3. 信号量操作

使用函数semop对信号量进行操作,如加锁(值减1)、解锁(值加1)。

#include <sys/sem.h>

// atomic array of operations on a semaphore set
int semop(int semid, struct sembuf *sops, size_t nsops);

参数

  • semid,信号量集的标识符
  • sops,信号量操作数组
  • nsops,结构体sembuf中的元素个数

3.1 信号量操作数组

sembuf定义如下:

struct sembuf {               /*信号量操作数组 */
    u_short sem_num;         /* semaphore # */
    short   sem_op;          /* semaphore operation */
    short   sem_flg;         /* operation flags */
};

(1)sem_num

sem_num,指定对信号量集中哪个信号进行操作,从0开始

(2)sem_op

对信号量进行操作,若值为n,大于0,给信号量(理解成资源的个数)加n个,小于0,相当于给资源数目减n

  • sem_op > 0, sem_val += sem_op

  • sem_op < 0, sem_val -= |sem_op|

  • sem_op = 0, sem_val = 0

(3)sem_flg

sem_flg有两个取值SEM_UNDOIPC_NOWAIT

  • SEM_UNDO: it will be automatically undone when the process terminates.
本文系Spark & Shine原创,转载需注明出处本文最近一次修改时间 2022-05-15 18:40

results matching ""

    No results matching ""