一、同一机器上
1、单生产者-单消费者
如果只有一个生产者和一个消费者,可以使用两个信号量 fillCount、emptyCount 来解决问题。
生产数据时:emptyCount--,进队,fillCount++。
消费数据时:fillCount--,出队,emptyCount++。
semaphore fillCount = 0; semaphore emptyCount = BUFFER_SIZE; void producer() { while (true) { item = produceItem(); down(emptyCount); putItemIntoBuffer(item); up(fillCount); } } void consumer() { while (true) { down(fillCount); item = removeItemFromBuffer(); up(emptyCount); consumeItem(item); } }2、多生产者-多消费者
如果有多个生产者和多个消费者,如果使用两个信号量 fillCount、emptyCount 来解决问题,可能会造成同时有多个数据写入同一个位置,同时有多个消费者从同一位置取数据,因此需要再加一个互斥锁。
mutex_t mutex; semaphore fillCount = 0; semaphore emptyCount = BUFFER_SIZE; procedure producer() { while (true) { item = produceItem() down(emptyCount) down(mutex) putItemIntoBuffer(item) up(mutex) up(fillCount) } up(fillCount) //the consumer may not finish before the producer. } procedure consumer() { while (true) { down(fillCount); down(mutex); item = removeItemFromBuffer(); up(mutex); up(emptyCount); consumeItem(item); } }也可以使用互斥量+两个条件变量,生产者、消费者分别在 full 和 empty 时阻塞。
mutex_t mutex; cond_t condunempty; cond_t condunfull; procedure producer() { while (true) { item = produceItem() lock(&mutex); if(qisfull){ cond_wait(&condunfull, &mutex); } putItemIntoBuffer(item); cond_signal(&condunempty); unlock(mutex); } } procedure consumer() { while (true) { lock(&mutex); if(qisempty){ cond_wait(&condunempty, &mutex); } item = removeItemFromBuffer(); cond_signal(&condunfull, &mutex); unlock(&mutex); } }
二、网络多级分布
