示例 4–14 中的数据结构与示例 4–11 中所示的用于条件变量示例的结构类似。两个信号分别表示空缓冲区和满缓冲区的数目,通过这些信号可确保生成方等待缓冲区变空,使用者等待缓冲区变满为止。
typedef struct { char buf[BSIZE]; sem_t occupied; sem_t empty; int nextin; int nextout; sem_t pmut; sem_t cmut; } buffer_t; buffer_t buffer; sem_init(&buffer.occupied, 0, 0); sem_init(&buffer.empty,0, BSIZE); sem_init(&buffer.pmut, 0, 1); sem_init(&buffer.cmut, 0, 1); buffer.nextin = buffer.nextout = 0;
另一对二进制信号与互斥锁作用相同。在多个生成方使用多个空缓冲槽位,以及多个使用者使用多个满缓冲槽位的情况下,信号可用来控制对缓冲区的访问。在这种情况下,使用互斥锁可能会更好,但这里主要是为了演示信号的用法。
void producer(buffer_t *b, char item) { sem_wait(&b->empty); sem_wait(&b->pmut); b->buf[b->nextin] = item; b->nextin++; b->nextin %= BSIZE; sem_post(&b->pmut); sem_post(&b->occupied); }
char consumer(buffer_t *b) { char item; sem_wait(&b->occupied); sem_wait(&b->cmut); item = b->buf[b->nextout]; b->nextout++; b->nextout %= BSIZE; sem_post(&b->cmut); sem_post(&b->empty); return(item); }