我有两个线程通过循环缓冲区进行通信。
/* Initialize not_full semaphore to a count of BUFFER_SIZE */
sem_init(¬_full_semaphore, 0, BUFFER_SIZE);
/* Initialize not_empty semaphore to a count of 0 */
sem_init(¬_empty_semaphore, 0, 0);
void producer_thread (void) {
int item
int head = 0;
while(true) {
item = produce_item();
sem_wait(¬_full_semaphore);
mutex_lock(&circular_buffer_mutex);
/* Insert item into the buffer */
circular_buffer[head] = item;
/* Increment head offset and wrap if necessary */
head = (head == BUFFER_SIZE - 1) ? 0 : head + 1;
mutex_unlock(&circular_buffer_mutex);
sem_post(¬_empty_semaphore);
}
}
void consumer_thread (void){
int item;
int tail = 0;
while(true) {
sem_wait(¬_empty_semaphore);
mutex_lock(&circular_buffer_mutex);
/* Remove item from the buffer */
item = circular_buffer[tail];
/* Increment tail offset and wrap if necessary */
tail = (tail == BUFFER_SIZE - 1) ? 0 : tail + 1;
mutex_unlock(&circular_buffer_mutex);
sem_post(¬_full_semaphore);
consume_item(item);
}
我的问题是我真的需要互斥体吗?在我看来,生产者和消费者不可能同时访问相同的内存。直到生产者完成书写并通过not_empty信号灯发出信号,消费者才会阅读。并且not_full信号量将阻止生产者重新包装并再次写入。因此,我似乎不需要互斥体,但是我发现的所有示例都使用了它。
答案 0 :(得分:0)
我的问题是我真的需要互斥锁吗?
是的。
没有互斥锁,因为您将not_full_semaphore
初始化为一个可能大于1的值,所以在此代码中:
while(true) {
item = produce_item();
sem_wait(¬_full_semaphore);
// can reach here while the consumer thread is
// accessing the circular buffer
// but this mutex prevents both threads from
// accessing the circular buffer simultaneously
mutex_lock(&circular_buffer_mutex);
您的生产者线程在生产下一个项目之前不会等待消费者线程完成。
not_full信号量将阻止生产者回绕并再次写。
那是不正确的。如果将not_full_semaphore
初始化为大于1的值,则生产者线程不必等待使用者线程。