SystemV 信号量(一) —— SystemV信号量的相关操作函数(semget / semop /semctl)

SystemV IPC 详解
本文详细介绍了SystemV IPC中的信号量机制,包括信号量集合创建、信号量初始化/销毁及信号量PV操作等核心概念与函数使用方法。

SystemV IPC 方案的相关内容都是通过 “房间密码”来创建房间,获取到房间的ID,后面其他进程也可以根据这个房间密码来拿到同一个房间的ID。这是理解下面这些操作函数的关键。


         目录

1、信号量集合的创建 semget

2、信号量的初始化 / 销毁 semctl

3、信号量的PV操作 semop


1、信号量集合的创建 semget

注意这里是信号量集合的创建,semget 可以一次创建多个信号量,为了管理这些信号量,统一把这些信号量放在一个信号量集合中,如果创建成功,返回的就是信号集的ID。

第一个参数 key:“房间密码”。通过ftok函数获取,。

第二个参数 nsem:信号量集合中信号量的个数。如果不打算创建 一个新的信号量集合的时候,该参数可以是0。

第三个参数 semflg:信号量集合的访问权限。通常是IPC_CREAT | 0666,如果信号量集合已经存在,那么信号量集合的访问权限会被修改成当前填入的权限。

返回值:成功返回信号量集合的ID,失败返回 -1

key_t key = ftok(".", 100);

// 创建一个信号量集合,该信号集包含2个信号量,访问权限为 0666
semget(key, 2, IPC_CREAT | 0666);

2、信号量的初始化 / 销毁 semctl

semctl 可以对信号量集合中的信号量进行初始化或者删除。因为现在只有信号量集合的ID,实际上我们要想操作信号量集合中的某一个信号量,需要先给这些信号量编号,然后根据编号来定向操作某一个信号量。

第一个参数 semid:信号量集合的ID

第二个参数 semnum:要操作信号量集合中的信号量编号。信号量集合给信号量编号的方式类似于数组下标,是从0开始的,所以为了区分哪个信号量是干什么用的,可以使用宏或者 枚举的方式来指明。如果第三个参数是IPC_RMID,当前参数会被无视。

// 枚举的方式
// SEM_WR: 对应下标0
// SEM_RD: 对应下标1
enum SEM
{
 SEM_WR,
 SEM_RD
};

// 宏定义的方式
#define SEM_WR 0
#define SEM_RD 1

第三个参数 cmd:要对信号量所作的操作。可选值如下:

可选值含义
GETVAL获取第 semnum 个信号量的值,当前函数的返回值就是获得值。
SETVAL设置信号量的值,需要用到第四个参数联合体
IPC_RMID删除当前信号量集合。此时第二个参数semnu会被无视

第四个参数:根据不同的cmd,可能需要传递参数。比如,当cmd=SETVAL时,需要填入第四个参数来告知当前函数,你想要要设置的值。第四个参数是一个联合体,联合体的格式如下:

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

   注意:使用该联合体的时候,需要自己手动声明。 

返回值:失败返回 -1;成功时会根据cmd的值返回不同的值(值是大于0的)

3、信号量的PV操作 semop

semop包含了对信号量集合中信号量的 P操作(申请) 和 V操作(释放)。

第一个参数 semid:信号量集合的ID

第二个参数 sops:输入型参数,要对信号量集合中的哪个信号量什么操作,阻塞方式又是怎样。结构体sembuf 的声明如下:

struct sembuf {
    unsigned short sem_num;     // 要操作的信号量的编号
    short sem_op;               // 对信号量进行的操作
                                // 1: 释放资源,V操作
                                // -1: 申请资源,P操作
    short sem_flg;             // 阻塞方式。0表示阻塞,IPC_NOWAIT表示非阻塞
};

   注意:如果要一次操作多个信号量,那么就需要定义一个sembuf类型的结构体数组

第三个参数 nsops:要操作的信号量的个数。一般是 1 

返回值:成功返回 0,失败返回 -1。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值