#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10 // 环形缓冲区大小
typedef struct
{
int *buffer; // 环形缓冲区
int head; // 缓冲区头指针
int tail; // 缓冲区尾指针
int count; // 缓冲区中元素个数
int size; // 缓冲区大小
pthread_mutex_t mutex; // 互斥锁
pthread_cond_t cond_prod; // 生产者条件变量
pthread_cond_t cond_cons; // 消费者条件变量
} ringbuffer_t;
ringbuffer_t buffer; // 环形缓冲区
sem_t sem_prod; // 生产者信号量
sem_t sem_cons; // 消费者信号量
void ringbuffer_init(ringbuffer_t *rb, int size)
{
rb->buffer = malloc(sizeof(int) * size);
rb->head = rb->tail = rb->count = 0;
rb->size = size;
pthread_mutex_init(&rb->mutex, NULL);
pthread_cond_init(&rb->cond_prod, NULL);
pthread_cond_init(&rb->cond_cons, NULL);
}
void ringbuffer_put(ringbuffer_t *rb, int value)
{
pthread_mutex_lock(&rb->mutex);
while (rb->count == rb->size)
{ // 缓冲区已满,等待消费者读取
pthread_cond_wait(&rb->cond_prod, &rb->mutex);
}
rb->buffer[rb->tail] = value; // 将元素放入缓冲区
rb->tail = (rb->tail + 1) % rb->size;
rb->count++;
pthread_cond_signal(&rb->cond_cons); // 通知消费者可以读取
pthread_mutex_unlock(&rb->mutex);
}
int ringbuffer_get(ringbuffer_t *rb)
{
int value = 0;
pthread_mutex_lock(&rb->mutex);
while (rb->count == 0)
{ // 缓冲区为空,等待生产者生产
pthread_cond_wait(&rb->cond_cons, &rb->mutex);
}
value = rb->buffer[rb->head]; // 从缓冲区中取出元素
rb->head = (rb->head + 1) % rb->size;
rb->count--;
pthread_cond_signal(&rb->cond_prod); // 通知生产者可以生产
pthread_mutex_unlock(&rb->mutex);
return value;
}
void *producer(void *arg)
{
int value = 0;
while (1)
{
sem_wait(&sem_prod); // 获取生产者信号量
value++;
ringbuffer_put(&buffer, value); // 将数据写入环形缓冲区
printf("producer: produced %d\n", value);
sem_post(&sem_cons); // 发送消费者信号量
}
pthread_exit(NULL);
}
void *consumer(void *arg)
{
int value = 0;
while (1)
{
sem_wait(&sem_cons); // 获取消费者信号量
value = ringbuffer_get(&buffer); // 从环形缓冲区中读取数据
printf("consumer: consumed %d\n", value);
sem_post(&sem_prod); // 发送生产者信号量
}
pthread_exit(NULL);
}
int main()
{
pthread_t prod_thread, cons_thread;
ringbuffer_init(&buffer, BUFFER_SIZE);
sem_init(&sem_prod, 0, BUFFER_SIZE); // 生产者初始信号量为缓冲区大小
sem_init(&sem_cons, 0, 0); // 消费者初始信号量为0
pthread_create(&prod_thread, NULL, producer, NULL);
pthread_create(&cons_thread, NULL, consumer, NULL);
pthread_join(prod_thread, NULL);
pthread_join(cons_thread, NULL);
sem_destroy(&sem_prod);
sem_destroy(&sem_cons);
pthread_mutex_destroy(&buffer.mutex);
pthread_cond_destroy(&buffer.cond_prod);
pthread_cond_destroy(&buffer.cond_cons);
free(buffer.buffer);
return 0;
}
生产者消费者简单应用案例(环形队列)
最新推荐文章于 2024-10-19 15:29:34 发布