Linux多线程实现生产者-消费者模型:代码示例与解析
Linux多线程实现生产者-消费者模型:代码示例与解析
本篇文章将通过代码示例演示使用Linux下的pthread库实现经典的生产者-消费者问题,并详细解释代码中的互斥锁和条件变量的使用。
代码示例
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define BUFFER_SIZE 5 // 缓冲区大小
int buffer[BUFFER_SIZE]; // 缓冲区数组
int count = 0; // 缓冲区中的数据个数
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁
pthread_cond_t full = PTHREAD_COND_INITIALIZER; // 缓冲区满条件变量
pthread_cond_t empty = PTHREAD_COND_INITIALIZER; // 缓冲区空条件变量
void* producer(void* arg) {
int num = *(int*)arg;
free(arg);
for (int i = 1; i <= 10; i++) {
pthread_mutex_lock(&mutex);
while (count == BUFFER_SIZE) {
// 缓冲区满,等待消费者消费
pthread_cond_wait(&full, &mutex);
}
buffer[count++] = i;
printf('Producer %d: produced item %d\n', num, i);
// 唤醒等待的消费者
pthread_cond_signal(&empty);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
void* consumer(void* arg) {
int num = *(int*)arg;
free(arg);
for (int i = 1; i <= 10; i++) {
pthread_mutex_lock(&mutex);
while (count == 0) {
// 缓冲区空,等待生产者生产
pthread_cond_wait(&empty, &mutex);
}
int item = buffer[--count];
printf('Consumer %d: consumed item %d\n', num, item);
// 唤醒等待的生产者
pthread_cond_signal(&full);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main() {
pthread_t producer_threads[2];
pthread_t consumer_threads[2];
// 创建生产者线程
for (int i = 0; i < 2; i++) {
int* arg = malloc(sizeof(int));
*arg = i + 1;
pthread_create(&producer_threads[i], NULL, producer, arg);
}
// 创建消费者线程
for (int i = 0; i < 2; i++) {
int* arg = malloc(sizeof(int));
*arg = i + 1;
pthread_create(&consumer_threads[i], NULL, consumer, arg);
}
// 等待所有线程完成
for (int i = 0; i < 2; i++) {
pthread_join(producer_threads[i], NULL);
pthread_join(consumer_threads[i], NULL);
}
return 0;
}
代码解释
该代码实现了一个生产者-消费者模型,其中包含以下关键部分:
- 缓冲区: 使用
buffer数组存储生产者生产的数据,count变量记录缓冲区中当前数据个数。 - 互斥锁: 使用
pthread_mutex_t类型的mutex变量来保证对缓冲区的访问是互斥的。 - 条件变量: 使用
pthread_cond_t类型的full和empty变量分别表示缓冲区满和缓冲区空两种条件。
生产者线程:
- 获取互斥锁。
- 如果缓冲区已满,则调用
pthread_cond_wait(&full, &mutex),阻塞等待条件变量full,直到有消费者取走数据。 - 将数据写入缓冲区。
- 唤醒等待的消费者线程,调用
pthread_cond_signal(&empty)。 - 释放互斥锁。
消费者线程:
- 获取互斥锁。
- 如果缓冲区为空,则调用
pthread_cond_wait(&empty, &mutex),阻塞等待条件变量empty,直到有生产者放入数据。 - 从缓冲区取出数据。
- 唤醒等待的生产者线程,调用
pthread_cond_signal(&full)。 - 释放互斥锁。
代码中的要点
- 该代码创建了两个生产者线程和两个消费者线程,每个生产者线程会依次生产数字1到10,每个消费者线程会依次取出缓冲区中的数据。
- 为了保证线程安全,对缓冲区的所有操作都需要在互斥锁的保护下进行。
- 使用条件变量可以有效地解决生产者和消费者之间的数据同步问题,避免出现资源争夺和死锁情况。
总结
本篇文章通过代码示例演示了如何使用Linux下的pthread库实现生产者-消费者模型,并解释了代码中互斥锁和条件变量的具体用法。该代码示例可以帮助读者更好地理解线程同步的概念,并为开发多线程应用程序提供一些实践经验。
原文地址: http://www.cveoy.top/t/topic/gInu 著作权归作者所有。请勿转载和采集!