在多线程编程中,生产者消费者模型是经典的同步问题。本文将以环形队列为缓冲区,在Linux环境下使用互斥锁和条件变量实现线程安全的生产者消费者模型,适合初学者理解并发控制的核心思想。
环形队列(Circular Queue)是一种使用固定大小数组并通过头尾指针循环利用空间的线性结构。它避免了普通队列频繁移动数据的开销,特别适合作为生产者和消费者之间的缓冲区。队列为空时,头尾指针相等;队列为满时,通常牺牲一个单元以区分空满状态,或使用计数器记录元素个数。
在Linux多线程环境中,共享资源(如环形队列)需要互斥锁(pthread_mutex_t)保护,防止数据竞争。同时,条件变量(pthread_cond_t)让线程在资源不可用时挂起等待,并在资源可用时被唤醒,避免忙等待。这正是生产者消费者模型高效运行的关键。
我们设计一个整型环形队列作为共享缓冲区,定义两个条件变量:not_full(队列未满,生产者可生产)和not_empty(队列非空,消费者可消费)。生产者在队列满时等待not_full,插入数据后通知not_empty;消费者在队列空时等待not_empty,取出数据后通知not_full。
// 环形队列结构typedef struct { int data; int capacity; int front, rear; int count; // 当前元素个数 pthread_mutex_t mutex; pthread_cond_t not_full, not_empty;} circular_queue;// 生产者void producer(void* arg) { circular_queue* q = (circular_queue*)arg; for (int i = 0; i < 100; ++i) { pthread_mutex_lock(&q->mutex); while (q->count == q->capacity) // 队列满 pthread_cond_wait(&q->not_full, &q->mutex); q->data[q->rear] = i; // 生产数据 q->rear = (q->rear + 1) % q->capacity; q->count++; pthread_cond_signal(&q->not_empty); pthread_mutex_unlock(&q->mutex); } return NULL;}// 消费者void* consumer(void* arg) { circular_queue* q = (circular_queue*)arg; for (int i = 0; i < 100; ++i) { pthread_mutex_lock(&q->mutex); while (q->count == 0) // 队列空 pthread_cond_wait(&q->not_empty, &q->mutex); int val = q->data[q->front]; // 消费数据 q->front = (q->front + 1) % q->capacity; q->count--; pthread_cond_signal(&q->not_full); pthread_mutex_unlock(&q->mutex); } return NULL;} 上述代码展示了如何在Linux下利用互斥锁和条件变量保护环形队列,实现线程安全的生产者消费者模型。注意while循环判断条件,防止虚假唤醒。
在Linux终端使用gcc编译:gcc -o prodcons prodcons.c -lpthread。运行程序,生产者不断放入数据,消费者不断取出数据,整个过程无数据丢失或重复,体现了环形队列与条件变量配合的优越性。
本文详细介绍了基于环形队列的生产者消费者模型在Linux下的实现,涵盖了多线程同步的核心概念——互斥锁和条件变量。通过此模型,开发者可以深入理解并发编程的同步技巧,为复杂系统设计打下基础。
本文由主机测评网于2026-02-19发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://vpshk.cn/20260225833.html