semget函数
- 作用:用于创建一个新的信号量集或者获取一个已经存在的信号量集标识符。其函数原型为
int semget(key_t key, int nsems, int semflg);
key
:是一个键值,用来标识一个特定的信号量集,通常使用 ftok
函数生成。
nsems
:指定信号量集中信号量的个数。
semflg
:是一组标志位,可用于指定创建或获取信号量集的方式,如 IPC_CREAT
(如果信号量集不存在则创建)、IPC_EXCL
(与 IPC_CREAT
一起使用,确保创建的信号量集是新的)等。
- 返回值:成功时返回信号量集的标识符,失败时返回 -1。
semop函数
- 作用:用于对信号量集中的信号量进行操作,如增加或减少信号量的值,从而实现同步和互斥等功能。其函数原型为
int semop(int semid, struct sembuf *sops, unsigned nsops);
semid
:是信号量集的标识符,由 semget
函数返回。
sops
:是一个指向 sembuf
结构体数组的指针,sembuf
结构体定义了对信号量的具体操作。
nsops
:指定 sops
数组中操作的个数。
sembuf
结构体:
sem_num
:指定要操作的信号量在信号量集中的索引(从 0 开始)。
sem_op
:指定对信号量的操作值。如果为正,表示释放资源(增加信号量的值);如果为负,表示请求资源(减少信号量的值),且其绝对值表示请求的资源数量;如果为 0,表示等待信号量的值变为 0。
sem_flg
:标志位,常用的有 IPC_NOWAIT
(操作不等待,立即返回)。
- 返回值:成功时返回 0,失败时返回 -1。
semctl函数
- 作用:用于对信号量集进行控制操作,如获取或设置信号量集的属性、删除信号量集等。其函数原型为
int semctl(int semid, int semnum, int cmd, ...);
semid
:信号量集的标识符,由 semget
函数返回。
semnum
:指定要操作的信号量在信号量集中的索引(从 0 开始),当 cmd
操作不针对特定信号量时,此参数可设为 0。
cmd
:指定要执行的控制命令,常见的命令有 IPC_RMID
(删除信号量集)、SETVAL
(设置信号量的值)、GETVAL
(获取信号量的值)等。
- 可变参数(
...
):根据 cmd
的不同而不同,例如当 cmd
为 SETVAL
时,需要传入一个 union semun
类型的参数来设置信号量的初始值。
union semun
联合体:
union semun {
int val; /* 用于 SETVAL */
struct semid_ds *buf; /* 用于 IPC_STAT, IPC_SET */
unsigned short *array; /* 用于 GETALL, SETALL */
struct seminfo *__buf; /* 用于 IPC_INFO (Linux-specific) */
};
- 返回值:成功时返回值依赖于
cmd
,失败时返回 -1。
调用顺序
- 首先调用
semget
函数创建信号量集或获取已存在信号量集的标识符。
- 然后可以调用
semctl
函数对信号量集进行初始化等控制操作,例如设置信号量的初始值。
- 在需要同步的代码段中,调用
semop
函数对信号量进行增减操作,以实现资源的请求和释放,从而达到同步的目的。
- 当不再需要信号量集时,调用
semctl
函数并使用 IPC_RMID
命令删除信号量集。