生产者与消费者问题(Producer-consumer problem),或称有限缓冲区问题(Bounded-buffer problem),是一个多线程/进程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两类线程:即“生产者”线程和“消费者”线程在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据(产品)放入缓冲区中,然后重复此过程。与此同时,消费者从缓冲区中取出数据并消耗。解决该问题的关键是如何保证生产者不会在缓冲区满时放入数据,而消费者也不会在缓冲区中空时消耗数据。使用POSIX thread库函数pthread_create创建若干个(至少2个)生产者线程和1个或若干个消费者线程,利用POSIX线程同步机制互斥锁和条件变量实现生产者线程和消费者线程的同步,生成程序流程
时间: 2024-03-04 10:48:00 浏览: 72
线程同步问题:生产者消费者
3星 · 编辑精心推荐
下面是一个使用POSIX thread库函数pthread_create创建多个生产者线程和多个消费者线程,并利用互斥锁和条件变量实现同步的程序流程:
1. 定义缓冲区和指针变量,用于存储和追踪数据。
2. 定义互斥锁和条件变量,用于保护和同步缓冲区和指针变量的访问。
3. 定义生产者线程和消费者线程的函数,分别实现生产者和消费者的行为。在生产者线程中,生产者首先尝试获取指针变量的互斥锁。如果缓冲区已满,则等待条件变量的信号。如果缓冲区未满,则将数据放入缓冲区,并通知消费者可以消费。在消费者线程中,消费者首先尝试获取指针变量的互斥锁。如果缓冲区为空,则等待条件变量的信号。如果缓冲区不为空,则从缓冲区中取出数据,并通知生产者可以生产。
4. 在主函数中,创建多个生产者线程和多个消费者线程,并启动它们。等待所有线程执行完毕,释放所有资源。
下面是一个简单的程序流程,仅供参考:
```c
#include <stdio.h>
#include <pthread.h>
#define BUFFER_SIZE 10
#define PRODUCER_NUM 2
#define CONSUMER_NUM 2
int buffer[BUFFER_SIZE];
int count = 0;
int in = 0;
int out = 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 id = *(int *)arg;
while (1) {
pthread_mutex_lock(&mutex);
while (count == BUFFER_SIZE) {
printf("producer %d waiting...\n", id);
pthread_cond_wait(&full, &mutex);
}
buffer[in] = 1;
printf("producer %d produced an item, count=%d\n", id, ++count);
in = (in + 1) % BUFFER_SIZE;
pthread_cond_signal(&empty);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
void *consumer(void *arg)
{
int id = *(int *)arg;
while (1) {
pthread_mutex_lock(&mutex);
while (count == 0) {
printf("consumer %d waiting...\n", id);
pthread_cond_wait(&empty, &mutex);
}
buffer[out] = 0;
printf("consumer %d consumed an item, count=%d\n", id, --count);
out = (out + 1) % BUFFER_SIZE;
pthread_cond_signal(&full);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main()
{
int i;
pthread_t producer_threads[PRODUCER_NUM];
pthread_t consumer_threads[CONSUMER_NUM];
int producer_ids[PRODUCER_NUM];
int consumer_ids[CONSUMER_NUM];
for (i = 0; i < PRODUCER_NUM; i++) {
producer_ids[i] = i + 1;
pthread_create(&producer_threads[i], NULL, producer, &producer_ids[i]);
}
for (i = 0; i < CONSUMER_NUM; i++) {
consumer_ids[i] = i + 1;
pthread_create(&consumer_threads[i], NULL, consumer, &consumer_ids[i]);
}
for (i = 0; i < PRODUCER_NUM; i++) {
pthread_join(producer_threads[i], NULL);
}
for (i = 0; i < CONSUMER_NUM; i++) {
pthread_join(consumer_threads[i], NULL);
}
return 0;
}
```
阅读全文