C语言 使用循环缓冲区和生产者/消费者设计模式时是否需要互斥体



我有两个线程通过循环缓冲区进行通信。

/* Initialize not_full semaphore to a count of BUFFER_SIZE */
sem_init(&not_full_semaphore, 0, BUFFER_SIZE);
/* Initialize not_empty semaphore to a count of 0 */
sem_init(&not_empty_semaphore, 0, 0);
void producer_thread (void) {
int item
int head = 0;
while(true) {
item = produce_item();
sem_wait(&not_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(&not_empty_semaphore);
}
}
void consumer_thread (void){
int item;
int tail = 0;
while(true) {
sem_wait(&not_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(&not_full_semaphore);
consume_item(item);
}

我的问题是我真的需要互斥锁吗? 在我看来,生产者和消费者不可能同时访问相同的内存。 在生产者完成写入并通过not_empty信号量发出信号之前,使用者不会读取。 并且生产者将被not_full信号灯阻止再次包装和写入。 所以在我看来,我似乎不需要互斥锁,但我找到的所有示例都使用了它。

我的问题是我真的需要互斥锁吗?

是的,你愿意。

如果没有互斥锁,由于您将not_full_semaphore初始化为可能大于 1 的值,因此在以下代码中:

while(true) {
item = produce_item();
sem_wait(&not_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 的值,则生产者线程不必等待使用者线程。

相关内容

最新更新