信号量是一个计数器,用于为多个进程提供对共享数据对象的访问。
为了获得共享资源,进程需要执行下列操作:
(1)测试控制该资源的信号量。
(2)若此信号量的值为正,则进程可以使用该资源,在这种情况下,进程会将信号量值减1,表示它使用了一个信号量的资源。
(3)否则,若此信号量的值为0,则进程进入休眠状态,直至信号量值大于0,进程被唤醒之后,将返回步骤(1)。
常用的信号量形式被称为二元信号量(binary semaphore)。它控制单个资源,其初始值为1,但是,一般而言,信号量的初值可以使任意一个正值,该值表明有多少个共享相关资源单位可供共享应用。
当使用XSI信号量时,首先需要通过调用函数semget来获得一个信号量ID。
| #include <sys/sem.h> int semget(key_t key, int nsems, int flag); 返回值:若成功,返回信号量ID;若出错,返回-1 |
|---|
nsems是该集合中的信号量数。如果是创建新集合,则必须指定nsems。如果是引用现有集合,则将nsems指定为0.
semctl函数更包含了多种信号量操作。
| #include <sys/sem.h> int semctl(int semid, int semum, int cmd, . . . /* union semun arg */); |
|---|
| 宏定义 | 作用 |
|---|---|
| IPC_STAT | 对此集合取semid_ds结构,并存储在由arg.buf指向的结构中。 |
| IPC_SET | 按arg.buf指向的结构中的值设置集合相关结构体中的相关成员。 |
| IPC_RMID | 从系统中删除该信号量集合。 |
| GETVAL | 返回成员semnum的semval值。 |
| SETVAL | 设置成员semnum的semval值。该值由arg.val指定。 |
| GETPID | 返回成员semnum的sempid的值。 |
| GETNCNT | 返回成员semnum的semncnt值 |
| GETZCNT | 返回成员semnum的semzcnt值。 |
| GETALL | 返回该集合中的所有的信号量值。 |
| SETALL | 将该集合中的所有的信号量设置成arg.array指向的数组中的值。 |
函数semop自动执行信号量集合上的操作数组。
| #include <sys/sem.h> int semop(int semid, struct sembuf semoparray[ ], size_t nops); 返回值:若成功,返回信号量ID;若出错,返回-1 |
|---|
参数semoparray是一个指针,它指向一个由sembuf结构表示的信号量操作数组。
struct sembuf {
unsigned short sem_num; / * member # in set (0, 1, …, nsems-1) * /
short sem_op; / * operation (negative, 0, or positive) * /
short sem_flg; / * IPC_NOWAIT, SEM_UNDO * /
};
参数nops规定该数组中操作的数量(元素数)。
对集合中的每个成员的操作由相应的sem_op值规定。此值可以是负值、0或者是正值。
(1)若sem_op为正值,则对应于进程释放占用的资源数。
(2)若sem_op为负值,则表示要获得由该信号量控制的资源。

本文深入解析信号量机制,包括信号量的基本概念、如何通过semget、semctl和semop函数进行信号量操作,以及信号量在进程间共享资源管理中的应用。
1909

被折叠的 条评论
为什么被折叠?



