APUE2中信号灯(semaphores)一节
来源:互联网 发布:三国志11日本武将数据 编辑:程序博客网 时间:2024/04/27 20:45
信号灯(semaphores):
信号灯和我们前面说的pipes, FIFOs, and message queues这些IPC 不一样,信号灯是多进程访问共享资源的一个计数器。
为了取得共享的资源,需要做下面几步:
1. 检查控制资源的信号灯。
2. 如果信号灯的值是正的,可以用这个资源,相应的信号灯的值会减一。
3. 如果信号灯的值是0,进程会阻塞至到信号灯的值大于0,当进程被唤醒,应该返回第一步操作。
当一个进程操作一个被信号灯控制的资源,信号灯被减1 ,其它进程将在信号灯的值增加后被唤醒。
为了正确的执行信号灯,检测信号灯值和减少信号灯的值都要在原子操作。由于这个原因,信号灯的操作都在操作系统内核级完成的。
一般的信号灯被叫做二进制的信号灯,它控制一个独立的资源,一开始被初始化为1 。然而有时候,信号灯被初始化为一个正值,这个值可以表示,有多少个资源被这个信号灯控制。
XSI semaphores 是一种更复杂的信号灯,三个特点造成了它的复杂性。
1. 它不是一个简单的非负的数值,而是一个或多个信号灯值的组合。当我们创建一个信号灯的时候,我们要指定信号灯值的个数。
2. 创建信号灯(semget)和初始化信号灯(semctl)是分开进行的。因为我们不能用原子操作来完成创建和初始化这两个步骤。
3. 所有的XSI IPC 在没有进程调用的时候,也会存在,我们可能会担心,如果一个进程分配了信号灯,但还没有释放,进程序就退出了,怎么办?我们下面说的,UNDO 特点就是解决这个问题。
内核为每个信号灯集合(semaphore set)维护一个semid_ds结构。
struct semid_ds {
struct ipc_perm sem_perm; /* see Section 15.6.2 */
unsigned short sem_nsems; /* # of semaphores in set */
time_t sem_otime; /* last-semop() time */
time_t sem_ctime; /* last-change time */
.
.
.
};
每个信号灯被一个结构表示(也可以说对应的有一个结构,译者注),这个结构至少包括下面几个项。
struct {
unsigned short semval; /* semaphore value, always >= 0 */
pid_t sempid; /* pid for last operation */
unsigned short semncnt; /* # processes awaiting semval>curval */
unsigned short semzcnt; /* # processes awaiting semval==0 */
.
.
.
};
(下面原文列了一些限制,此处不译,可以查看原文)
第一个函数是获得信号灯的ID ,semget
#include <sys/sem.h>
int semget(key_t key, int nsems, int flag);
Returns: semaphore ID if OK, 1 on error
在Section 15.6.1(其它章节),我们讨论转换一个KEY 到一个标识符(应该是指ID 吧,译者注)。被调用的集合可能是新建的也可能是已经存在的。当一个新的集合被创建,下面的semid_ds 成员被初始化。
ipc_perm 被初始化
· sem_otime 初始化为 0.
sem_ctime 初始化为当前时间。
· sem_nsems 初始化为nsems.
集合中信号灯的元素个数就是nsems,创建新集合时(在server上),nsems 必须赋值,调用集合时(在client 上),nsems 可以指定为0
函数semctl 可以进行大多数信号灯的操作。
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd,
... /* union semun arg */);
Returns: (see following)
第四个参数是可变的,具体视CMD 参数而定,semun 是一个命令参数的组合。
union semun {
int val; /* for SETVAL */
struct semid_ds *buf; /* for IPC_STAT and IPC_SET */
unsigned short *array; /* for GETALL and SETALL */
};
注意:第四个参数是union , 不是union 的指针。
CMD 可以用下面十条命令,来处理 semid 指定的集合。有五条命令涉及到了信号灯集合中的某个元素,通过semnum来指定,semnum的值在0—nsems-1 之间。
IPC_STAT 取得集合的semid_ds结构体,存放到arg.buf指针所指的空间。
IPC_SET 设置sem_perm.uid, sem_perm.gid, and sem_perm.mode值,这条命令的只能在effective user ID 等于 sem_perm.cuid or sem_perm.uid 或者有超级用户权限的情况下,才可以执行
IPC_RMID 删除信号灯集合。删除是即时起作用的,任何调用该集合的进程会得到一个错误值EIDRM,这条命令需要的执行权限和上一条相同。
GETVAL 返回集合中semnum成员的值semval
SETVAL 设置集合中semnum成员的值semval,,值在arg.val中指定。
GETPID 返回集合中semnum成员的sempid 值
GETNCNT 返回集合中semnum成员的semncnt值
GETZCNT 返回集合中semnum成员的semzcnt值
GETALL 得到信号灯中所有的值,存放在arg.array 中
SETALL 得到信号灯中所有的值,存放在arg.array 中
除了GETALL的所有GET命令,返回相应的值,其余的命令返回0
Semop 对信号灯集合进行一组原子操作。
#include <sys/sem.h>
int semop(int semid, struct sembuf semoparray[],
size_t nops);
Returns: 0 if OK, 1 on error
Semoparray 这个参数是一组操作命令的指针,nops 是这组命令的个数。
Semoparray 是一个结构体,声明如下:
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 */
};
sem_op 的值指定集合中的某个元素,可以为负,0,正。
1. 最简单的情况就是sem_op为正,直接为进程返回相应的资源,sem_op的值被加到信号灯值。Undo的标志被指定,就把信号灯的值减去sem_op的值。
2. 如果sem_op 是负的,我们想要获得相应的资源。如果信号灯的值大于或等于sem_op的绝对值,那么信号灯的值减去sem_op的绝对值。这保证了信号灯的值能大于等于0。如果undo 标志被指定,就进行相应的加操作。
如果信号灯的值小于sem_op,将会发生下面的几种情况。
a. 如果IPC_NOWAIT被指定,semop函数将返回EAGAIN的错误值。
b. 如果IPC_NOWAIT没有指定,信号灯的semncnt值被加1,调用者被阻塞,直到下面的情况发生。
信号灯的值大于或等于sem_op的绝对值;
信号灯被删除
调用者进程处理信号,并且退出信号处理。
4.如果sem_op 为0,这意味着调用者进程将等待信号灯的值变为0。
如果信号灯的值为0,函数会马上返回。
如果信号灯的值不为0,下面几种情况会发生。
如果IPC_NOWAIT的值被指定,函数返回错误值EAGAIN;
如果IPC_NOWAIT 的值没指定,函数将等待。
Semop的操作是原子性的,要么完成一系列的操作,要么一点都不做。
- APUE2中信号灯(semaphores)一节
- Semaphores
- Semaphores
- 多线程同步之Semaphores(信号量)
- Win32多线程之信号量(Semaphores)
- Linux 进程间通信 - 信号灯(Semaphores)
- chdir、fchdir 和 getcwd 函数(APUE2 4.22节)
- apue2读书笔记
- 中信证券的丑恶行经(南京营业部)
- Java培训笔记十二(中信的Java基础归纳)
- 瓶中信
- 网口信号灯的作用
- 《Win32多线程程序设计》(5)---信号量(Semaphores)
- HTML 第十一节(CSS选择器)
- APUE2作者提供的源码编译方法及单个源码编译的实现(转载)
- APUE2作者提供的源码编译方法及单个源码编译的实现(转载)
- Ubuntu 12.04 配置apue2环境(《unix环境高级编程》源码编译环境安装)
- APUE2习题3.2
- 初识 EXT3.0 中的 chart
- [双语阅读]调查:瑞士工资水平居全球之首
- 090831项目进展:smb资源的深层递归2
- 数据库分页,Oracle 和 mysql
- 伽玛函数
- APUE2中信号灯(semaphores)一节
- [双语阅读]日民主党完胜 鸠山承诺将耐心谦虚
- 联发科山寨崛起,却成台湾手机产业掘墓人
- TPtr8 转换到TDes8奇怪问题
- 成功女性的十个好习惯
- 素面朝天 makeunder
- 蜡像 wax figure
- JNI入门学习笔记
- 密室交易 backroom deal