c语言 利用线程编写程序,实现对生产者消费者问题的模拟。
时间: 2023-05-30 14:01:38 浏览: 125
生产消费问题模拟实现
生产者消费者问题是一个经典的同步问题,其主要涉及两个角色:生产者和消费者。生产者负责生产产品并将其放入缓冲区中,而消费者则负责从缓冲区中取出产品并将其消耗掉。由于生产者和消费者的速度可能不同,因此需要通过某种机制来保证两者之间的同步和互斥。
利用线程编写程序来模拟生产者消费者问题,可以采用如下的算法:
1. 定义缓冲区数据结构,包括缓冲区大小、缓冲区中已有产品数量以及产品队列。
2. 定义生产者和消费者线程。
3. 生产者线程循环执行如下操作:
a. 检查缓冲区是否已满,如果已满则等待。
b. 向缓冲区中添加产品。
c. 增加缓冲区中已有产品数量。
d. 如果缓冲区之前为空,则唤醒等待的消费者线程。
4. 消费者线程循环执行如下操作:
a. 检查缓冲区是否为空,如果为空则等待。
b. 从缓冲区中取出产品。
c. 减少缓冲区中已有产品数量。
d. 如果缓冲区之前已满,则唤醒等待的生产者线程。
5. 在主函数中创建生产者和消费者线程,并等待它们结束。
下面是一个简单的示例代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;
int count = 0;
pthread_mutex_t mutex;
pthread_cond_t full;
pthread_cond_t empty;
void *producer(void *arg) {
int item;
while (1) {
// 生产产品
item = rand() % 100;
// 加锁
pthread_mutex_lock(&mutex);
while (count == BUFFER_SIZE) {
// 缓冲区已满,等待
pthread_cond_wait(&full, &mutex);
}
// 将产品放入缓冲区
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
count++;
if (count == 1) {
// 缓冲区之前为空,唤醒消费者线程
pthread_cond_signal(&empty);
}
// 解锁
pthread_mutex_unlock(&mutex);
}
return NULL;
}
void *consumer(void *arg) {
int item;
while (1) {
// 消费产品
item = buffer[out];
// 加锁
pthread_mutex_lock(&mutex);
while (count == 0) {
// 缓冲区为空,等待
pthread_cond_wait(&empty, &mutex);
}
// 从缓冲区取出产品
out = (out + 1) % BUFFER_SIZE;
count--;
if (count == BUFFER_SIZE - 1) {
// 缓冲区之前已满,唤醒生产者线程
pthread_cond_signal(&full);
}
// 解锁
pthread_mutex_unlock(&mutex);
// 消费产品
printf("Consumer %ld consumed item %d\n", (long) arg, item);
}
return NULL;
}
int main() {
pthread_t p1, p2, c1, c2;
// 初始化互斥锁和条件变量
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&full, NULL);
pthread_cond_init(&empty, NULL);
// 创建生产者线程
pthread_create(&p1, NULL, producer, NULL);
pthread_create(&p2, NULL, producer, NULL);
// 创建消费者线程
pthread_create(&c1, NULL, consumer, (void *) 1);
pthread_create(&c2, NULL, consumer, (void *) 2);
// 等待线程结束
pthread_join(p1, NULL);
pthread_join(p2, NULL);
pthread_join(c1, NULL);
pthread_join(c2, NULL);
// 销毁互斥锁和条件变量
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&full);
pthread_cond_destroy(&empty);
return 0;
}
```
在上述代码中,我们使用了互斥锁和条件变量来实现线程之间的同步和互斥。互斥锁用于保护共享资源,防止多个线程同时访问。条件变量用于线程之间的通信,允许线程等待某个条件的发生,并在条件满足时被唤醒。在生产者消费者问题中,我们使用了两个条件变量,分别用于表示缓冲区是否已满和是否为空。当缓冲区已满时,生产者线程应该等待,直到有一个消费者取出了一个产品,使得缓冲区不再满。当缓冲区为空时,消费者线程应该等待,直到有一个生产者放入了一个产品,使得缓冲区不再为空。这种等待和唤醒的机制可以确保生产者和消费者之间的同步和互斥。
阅读全文