基于生产者消费者问题用C 实现并发编程
以下是一个基于生产者消费者问题的C程序,使用了线程和互斥锁来实现并发编程:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define BUFFER_SIZE 10 // 缓冲区大小
#define PRODUCER_NUM 3 // 生产者数量
#define CONSUMER_NUM 2 // 消费者数量
int buffer[BUFFER_SIZE]; // 缓冲区
int in = 0; // 生产者将数据写入缓冲区的位置
int out = 0; // 消费者从缓冲区读取数据的位置
pthread_mutex_t mutex; // 互斥锁
pthread_cond_t full; // 缓冲区满条件变量
pthread_cond_t empty; // 缓冲区空条件变量
void *producer(void *arg) {
int id = *(int *)arg;
while (1) {
int item = rand() % 100; // 生成一个随机数作为生产的数据
pthread_mutex_lock(&mutex); // 加锁
while ((in + 1) % BUFFER_SIZE == out) { // 缓冲区已满,等待消费者消费
printf("Producer %d: buffer is full, waiting for consumer...\n", id);
pthread_cond_wait(&full, &mutex);
}
buffer[in] = item; // 将数据写入缓冲区
printf("Producer %d: produce item %d\n", id, item);
in = (in + 1) % BUFFER_SIZE; // 更新写入位置
pthread_cond_signal(&empty); // 发送缓冲区非空信号给消费者
pthread_mutex_unlock(&mutex); // 解锁
}
}
void *consumer(void *arg) {
int id = *(int *)arg;
while (1) {
pthread_mutex_lock(&mutex); // 加锁
while (in == out) { // 缓冲区为空,等待生产者生产
printf("Consumer %d: buffer is empty, waiting for producer...\n", id);
pthread_cond_wait(&empty, &mutex);
}
int item = buffer[out]; // 从缓冲区读取数据
printf("Consumer %d: consume item %d\n", id, item);
out = (out + 1) % BUFFER_SIZE; // 更新读取位置
pthread_cond_signal(&full); // 发送缓冲区非满信号给生产者
pthread_mutex_unlock(&mutex); // 解锁
}
}
int main() {
pthread_t producers[PRODUCER_NUM];
pthread_t consumers[CONSUMER_NUM];
int producer_ids[PRODUCER_NUM];
int consumer_ids[CONSUMER_NUM];
int i;
// 初始化互斥锁和条件变量
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&full, NULL);
pthread_cond_init(&empty, NULL);
// 创建生产者线程
for (i = 0; i < PRODUCER_NUM; i++) {
producer_ids[i] = i + 1;
pthread_create(&producers[i], NULL, producer, &producer_ids[i]);
}
// 创建消费者线程
for (i = 0; i < CONSUMER_NUM; i++) {
consumer_ids[i] = i + 1;
pthread_create(&consumers[i], NULL, consumer, &consumer_ids[i]);
}
// 等待线程结束
for (i = 0; i < PRODUCER_NUM; i++) {
pthread_join(producers[i], NULL);
}
for (i = 0; i < CONSUMER_NUM; i++) {
pthread_join(consumers[i], NULL);
}
// 销毁互斥锁和条件变量
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&full);
pthread_cond_destroy(&empty);
return 0;
}
在该程序中,生产者线程和消费者线程都是无限循环,不断地进行生产和消费。生产者线程生成一个随机数作为生产的数据,然后将数据写入缓冲区中。如果缓冲区已满,生产者线程会等待消费者线程消费数据,直到缓冲区非满。消费者线程从缓冲区中读取数据,如果缓冲区为空,消费者线程会等待生产者线程生产数据,直到缓冲区非空。
在生产者线程和消费者线程之间,使用了互斥锁来保证缓冲区的互斥访问。当一个线程持有互斥锁时,另一个线程必须等待该锁被释放才能访问共享资源。此外,还使用了条件变量来实现线程之间的同步。当一个线程等待某个条件变量时,它会释放互斥锁,并等待条件变量被另一个线程发送信号。当另一个线程发送信号时,等待的线程会重新获得互斥锁,并继续执行。
最后,需要注意的是,在生产者消费者问题中,使用互斥锁和条件变量时需要注意避免死锁和饥饿等问题。例如,如果一个线程持有互斥锁并等待条件变量时,另一个线程也需要获得该锁才能访问共享资源,但如果该锁一直被第一个线程持有,第二个线程就会一直等待,导致饥饿问题。因此,在编写生产者消费者问题的程序时,需要仔细考虑线程之间的交互和同步方式,以确保程序的正确性和效率。
原文地址: https://www.cveoy.top/t/topic/b5TJ 著作权归作者所有。请勿转载和采集!