struct sembuf的部分讲解

来源:互联网 发布:hap软件下载 编辑:程序博客网 时间:2024/06/09 15:02

sembuf结构体的定义如下:

[cpp] view plain copy
 
 
  1. struct sembuf  
  2. {  
  3.   unsigned short int sem_num;   /* 信号量的序号从0~nsems-1 */  
  4.   short int sem_op;            /* 对信号量的操作,>0, 0, <0 */  
  5.   short int sem_flg;            /* 操作标识:0, IPC_WAIT, SEM_UNDO */  
  6. };  

sem_num标识信号量集中的第几个信号量,0表示第1个,1表示第2个,nsems - 1表示最后一个。

sem_op标识对信号量的所进行的操作类型。对信号量的操作有三种类型:

  • sem_op > 0,对该信号量执行挂出操作,挂出的值由sem_op决定,系统会把sem_op的值加到该信号量的当前值semval(参考文章开头关于每个信号量结构的定义)上。如果sem_flag指定了SEM_UNDO(还原)标志,那么相应信号量的semadj值会减掉sem_op的值。下面会说明semadj的含义。
  • sem_op < 0,对该信号量执行等待操作,当信号量的当前值semval >= -sem_op时,semval减掉sem_op的绝对值,为该线程分配对应数目的资源。如果指定SEM_UNDO,相应信号量的semadj就加上sem_op的绝对值。当semval < -sem_op时,相应信号量的semncnt就加1,调用线程被阻塞,直到semval >= -sem_op,当此条件满足时,调用线程被唤醒,执行相应的分配操作,然后semncnt减去1.
  • sem_op = 0,表示调用者希望semval变为0。如果为0则立即返回,如果不为0,相应信号量的semzcnt1,调用调用线程被阻塞。

sem_flag:信号量操作的属性标志,如果为0,表示正常操作,如果为IPC_WAIT,使对信号量的操作时非阻塞的。即指定了该标志,调用线程在信号量的值不满足条件的情况下不会被阻塞,而是直接返回-1,并将errno设置为EAGAIN。如果为SEM_UNDO,那么将维护进程对信号量的调整值,以便进程结束时恢复信号量的状态。

下面解释一下与单个信号量相关的几个值:

semval:信号量的当前值,在文章开头信号量的结构中已提到。

semncnt:等待semval变为大于当前值的线程数。在文章开头信号量的结构中已提到。

semzcnt:等待semval变为0的线程数。在文章开头信号量的结构中已提到。

semadj:指定信号量针对某个特定进程的调整值。只有sembuf结构的sem_flag指定为SEM_UNDO后,semadj才会随着sem_op而更新。讲简单一点:对某个进程,在指定SEM_UNDO后,对信号量semval值的修改都会反应到semadj上,当该进程终止的时候,内核会根据semadj的值,重新恢复信号量之前的值