用c语言写一个简单的基于阻塞队列的生产者与消费者模型
时间: 2023-08-31 19:29:09 浏览: 262
### 回答1:
下面是一个简单的基于阻塞队列的生产者与消费者模型的 C 语言代码示例:
```
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define MAX_ITEMS 5
int queue[MAX_ITEMS];
int front = 0;
int rear = -1;
int count = 0;
sem_t empty_sem;
sem_t full_sem;
pthread_mutex_t queue_mutex;
void *producer(void *arg) {
int item;
while (1) {
item = rand() % 100;
sem_wait(&empty_sem);
pthread_mutex_lock(&queue_mutex);
queue[++rear] = item;
count++;
printf("Produced item: %d\n", item);
pthread_mutex_unlock(&queue_mutex);
sem_post(&full_sem);
}
}
void *consumer(void *arg) {
int item;
while (1) {
sem_wait(&full_sem);
pthread_mutex_lock(&queue_mutex);
item = queue[front++];
count--;
printf("Consumed item: %d\n", item);
pthread_mutex_unlock(&queue_mutex);
sem_post(&empty_sem);
}
}
int main() {
pthread_t producer_thread, consumer_thread;
sem_init(&empty_sem, 0, MAX_ITEMS);
sem_init(&full_sem, 0, 0);
pthread_mutex_init(&queue_mutex, NULL);
pthread_create(&producer_thread, NULL, producer, NULL);
pthread_create(&consumer_thread, NULL, consumer, NULL);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
return 0;
}
```
说明:这里使用了两个信号量 `empty_sem` 和 `full_sem` 以及一个互斥锁 `queue_mutex` 来实现生产者与消费者间的同步和互斥。当队列为空时,消费者线程将等待 `full_sem` 信号量;当队列已满时,生产者线程将等待 `empty_sem` 信号量。读写队列数据时,使用互斥锁来保证
### 回答2:
生产者-消费者模型是一种常见的多线程编程模型,在多线程环境下,由一个或多个生产者线程生成数据并将其放入缓冲区,然后由一个或多个消费者线程从缓冲区中取出数据进行消费。阻塞队列是一个可以自动阻塞或唤醒线程的队列,当队列为空时,消费者线程将被阻塞,直到有生产者线程向队列中放入数据;当队列满时,生产者线程将被阻塞,直到有消费者线程从队列中取出数据。
下面是一个基于C语言的简单生产者-消费者模型,使用阻塞队列实现。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_QUEUE_SIZE 10
typedef struct {
int data[MAX_QUEUE_SIZE];
int front;
int rear;
int count;
pthread_mutex_t mutex;
pthread_cond_t not_full;
pthread_cond_t not_empty;
} BlockingQueue;
void init_queue(BlockingQueue* queue) {
queue->front = 0;
queue->rear = 0;
queue->count = 0;
pthread_mutex_init(&queue->mutex, NULL);
pthread_cond_init(&queue->not_full, NULL);
pthread_cond_init(&queue->not_empty, NULL);
}
void enqueue(BlockingQueue* queue, int item) {
pthread_mutex_lock(&queue->mutex);
while (queue->count >= MAX_QUEUE_SIZE) {
pthread_cond_wait(&queue->not_full, &queue->mutex);
}
queue->data[queue->rear] = item;
queue->rear = (queue->rear + 1) % MAX_QUEUE_SIZE;
queue->count++;
pthread_cond_signal(&queue->not_empty);
pthread_mutex_unlock(&queue->mutex);
}
int dequeue(BlockingQueue* queue) {
pthread_mutex_lock(&queue->mutex);
while (queue->count <= 0) {
pthread_cond_wait(&queue->not_empty, &queue->mutex);
}
int item = queue->data[queue->front];
queue->front = (queue->front + 1) % MAX_QUEUE_SIZE;
queue->count--;
pthread_cond_signal(&queue->not_full);
pthread_mutex_unlock(&queue->mutex);
return item;
}
void* producer(void* arg) {
BlockingQueue* queue = (BlockingQueue*)arg;
for (int i = 1; i <= 100; i++) {
enqueue(queue, i);
printf("Producer produced: %d\n", i);
}
pthread_exit(NULL);
}
void* consumer(void* arg) {
BlockingQueue* queue = (BlockingQueue*)arg;
for (int i = 1; i <= 100; i++) {
int item = dequeue(queue);
printf("Consumer consumed: %d\n", item);
}
pthread_exit(NULL);
}
int main() {
BlockingQueue queue;
init_queue(&queue);
pthread_t producer_thread;
pthread_t consumer_thread;
pthread_create(&producer_thread, NULL, producer, &queue);
pthread_create(&consumer_thread, NULL, consumer, &queue);
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
return 0;
}
上述代码中,定义了一个BlockingQueue结构体来表示阻塞队列,使用互斥锁(mutex)和条件变量(cond)来实现线程之间的同步和互斥。生产者线程使用enqueue函数将数据放入队列,消费者线程使用dequeue函数从队列中取出数据。生产者线程生成1到100的数据并放入队列,消费者线程从队列中取出数据并输出。
此模型通过互斥锁和条件变量的配合,实现了生产者线程与消费者线程之间的同步,当队列满时生产者线程阻塞等待,当队列空时消费者线程阻塞等待,从而避免了线程间的数据竞争和死锁问题。
### 回答3:
阻塞队列是一种常用的线程同步机制,它提供了安全的生产者-消费者模型。下面是一个使用C语言实现的简单的基于阻塞队列的生产者与消费者模型的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define BUFFER_SIZE 5
typedef struct {
int buffer[BUFFER_SIZE];
int size;
int in;
int out;
pthread_mutex_t mutex;
pthread_cond_t full;
pthread_cond_t empty;
} Queue;
void produce(Queue* q, int val) {
pthread_mutex_lock(&(q->mutex));
while (q->size == BUFFER_SIZE) {
pthread_cond_wait(&(q->full), &(q->mutex));
}
q->buffer[q->in] = val;
q->in = (q->in + 1) % BUFFER_SIZE;
q->size++;
pthread_cond_signal(&(q->empty));
pthread_mutex_unlock(&(q->mutex));
}
int consume(Queue* q) {
pthread_mutex_lock(&(q->mutex));
while (q->size == 0) {
pthread_cond_wait(&(q->empty), &(q->mutex));
}
int val = q->buffer[q->out];
q->out = (q->out + 1) % BUFFER_SIZE;
q->size--;
pthread_cond_signal(&(q->full));
pthread_mutex_unlock(&(q->mutex));
return val;
}
void* producer(void* arg) {
Queue* q = (Queue*)arg;
for (int i = 1; i <= 10; i++) {
produce(q, i);
printf("Produced: %d\n", i);
}
pthread_exit(NULL);
}
void* consumer(void* arg) {
Queue* q = (Queue*)arg;
for (int i = 1; i <= 10; i++) {
int val = consume(q);
printf("Consumed: %d\n", val);
}
pthread_exit(NULL);
}
int main() {
Queue q;
q.size = 0;
q.in = 0;
q.out = 0;
pthread_mutex_init(&(q.mutex), NULL);
pthread_cond_init(&(q.full), NULL);
pthread_cond_init(&(q.empty), NULL);
pthread_t producer_thread, consumer_thread;
pthread_create(&producer_thread, NULL, producer, (void*)(&q));
pthread_create(&consumer_thread, NULL, consumer, (void*)(&q));
pthread_join(producer_thread, NULL);
pthread_join(consumer_thread, NULL);
pthread_cond_destroy(&(q.full));
pthread_cond_destroy(&(q.empty));
pthread_mutex_destroy(&(q.mutex));
return 0;
}
```
该示例中,我们定义了一个用于线程间共享的队列结构体,并使用互斥锁(`mutex`)和条件变量(`full`和`empty`)保证了生产者与消费者之间的同步。生产者通过`produce`函数将数据存入队列中,如果队列已满,则阻塞等待直到有空间可用。消费者通过`consume`函数从队列中取出数据,如果队列为空,则阻塞等待直到有数据可用。在`main`函数中创建了一个生产者线程和一个消费者线程,并使用`pthread_join`函数等待线程执行结束。
该示例中,生产者线程会依次将数值1~10存入队列中,消费者线程会依次从队列中取出数值并打印。通过互斥锁和条件变量的使用,保证了生产者与消费者之间的正确同步,避免了生产者在队列已满时继续生产以及消费者在队列为空时继续消费的问题。
阅读全文