semop函数
使用semget打开一个信号量集后,对其中一个或多个信号量的操作就使用semop函数来执行。
#include
int semop(int semid, struct sembuf *opsptr, size_t nops);
返回:若成功则为0,若出错则为-1
struct sembuf {
short sem_num;   /*信号量值:0,1...,nsems-1*/
short sem_op;    /*对于指定信号量sem_num的操作*/
short sem_flg;   /*操作标记*/
};
nops指定由opsptr指向的sembuf结构数组中元素的数目。
该数组中的每个元素给目标信号集内某个特定的信号量指定一个操作。这个特定的信号量由sem_num指定,0代表第一个元素,1代表第二个元素,依次类推,直到nsems-1,其中nsems是目标信号量集内成员信号量的数目(也就是创建信号量集合时传递给semget的第二个参数)。


struct sembuf ops[2];
ops[0].sem_num = 0;   /*wait for [0] to be 0*/
ops[0].sem_op = 0;
ops[0].sem_flg = 0;
ops[1].sem_num = 0;   /*then increment [0] by 1*/
ops[1].sem_op = 1;
ops[1].sem_flg = SEM_UNDO;


sem_op取值:
1.如果是正数,其值就加到semval上。这对应于释放由某个信号量控制的资源
  如果指定了SEM_UNDO标志,那就从相应信号量的semadj值中减去sem_op的值
2.如果sem_op为0,那么调用者希望等待到semval变为0.如果semval已经是0,那就立即返回
  如果semval不为0,相应信号量的semzcnt值就加1,调用线程则被阻塞到semval变为0(到那时,相应信号量的semzcnt值再减1)
  如果指定了IPC_NOWAIT标志,调用线程就不会被投入睡眠。
3.如果sem_op是负数,那么调用者希望等待semval变为大于或等于sem_op的绝对值。这对应于分配资源。
  如果semval大于sem_op的绝对值,那就从semval中减掉sem_op的绝对值。如果指定了SEM_UNDO标志,那么sem_op的绝对值就加到相应信号量的semadj值上。
  如果semval小于sem_op的绝对值,相应信号量的semncnt值就加1,调用线程则被阻塞到semval变为大于或等于sem_op的绝对值
10-22 21:17