以生产者/消费者模型为依据,在linux环境下创建一个控制台进程,在该进 程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
时间: 2024-02-12 13:09:38 浏览: 27
好的,以下是一个基于生产者/消费者模型的控制台程序,在Linux环境下创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10 // 缓冲区大小
#define PRODUCER_NUM 3 // 生产者数量
#define CONSUMER_NUM 2 // 消费者数量
int buffer[BUFFER_SIZE]; // 缓冲区
int in = 0; // 缓冲区写指针
int out = 0; // 缓冲区读指针
sem_t empty_sem; // 空缓冲区信号量
sem_t full_sem; // 满缓冲区信号量
pthread_mutex_t mutex; // 互斥锁
// 生产者线程
void *producer(void *arg) {
int id = *(int *)arg;
while (1) {
// 生成一个随机数表示新生产的物品
int item = rand() % 100 + 1;
// 等待空缓冲区
sem_wait(&empty_sem);
// 获取互斥锁
pthread_mutex_lock(&mutex);
// 将物品放入缓冲区
buffer[in] = item;
printf("Producer %d produced item %d.\n", id, item);
in = (in + 1) % BUFFER_SIZE;
// 释放互斥锁
pthread_mutex_unlock(&mutex);
// 发送满缓冲区信号
sem_post(&full_sem);
// 等待一段时间再继续生产
sleep(rand() % 3 + 1);
}
}
// 消费者线程
void *consumer(void *arg) {
int id = *(int *)arg;
while (1) {
// 等待满缓冲区
sem_wait(&full_sem);
// 获取互斥锁
pthread_mutex_lock(&mutex);
// 从缓冲区取出物品
int item = buffer[out];
printf("Consumer %d consumed item %d.\n", id, item);
out = (out + 1) % BUFFER_SIZE;
// 释放互斥锁
pthread_mutex_unlock(&mutex);
// 发送空缓冲区信号
sem_post(&empty_sem);
// 等待一段时间再继续消费
sleep(rand() % 3 + 1);
}
}
int main() {
// 初始化信号量和互斥锁
sem_init(&empty_sem, 0, BUFFER_SIZE);
sem_init(&full_sem, 0, 0);
pthread_mutex_init(&mutex, NULL);
// 创建生产者线程
pthread_t producer_threads[PRODUCER_NUM];
int producer_ids[PRODUCER_NUM];
for (int i = 0; i < PRODUCER_NUM; i++) {
producer_ids[i] = i + 1;
pthread_create(&producer_threads[i], NULL, producer, &producer_ids[i]);
}
// 创建消费者线程
pthread_t consumer_threads[CONSUMER_NUM];
int consumer_ids[CONSUMER_NUM];
for (int i = 0; i < CONSUMER_NUM; i++) {
consumer_ids[i] = i + 1;
pthread_create(&consumer_threads[i], NULL, consumer, &consumer_ids[i]);
}
// 等待所有线程结束
for (int i = 0; i < PRODUCER_NUM; i++) {
pthread_join(producer_threads[i], NULL);
}
for (int i = 0; i < CONSUMER_NUM; i++) {
pthread_join(consumer_threads[i], NULL);
}
// 销毁信号量和互斥锁
sem_destroy(&empty_sem);
sem_destroy(&full_sem);
pthread_mutex_destroy(&mutex);
return 0;
}
```
在上述代码中,我们使用了两个信号量empty_sem和full_sem,它们分别表示空缓冲区和满缓冲区。同时,我们还使用了一个互斥锁mutex,用于确保同一时刻只有一个线程对缓冲区进行操作。生产者线程通过sem_wait等待空缓冲区信号,然后获取互斥锁,将新的物品放入缓冲区,释放互斥锁,最后发送满缓冲区信号。消费者线程则通过sem_wait等待满缓冲区信号,然后获取互斥锁,从缓冲区取出物品,释放互斥锁,最后发送空缓冲区信号。在程序运行过程中,生产者和消费者线程会交替进行,确保缓冲区中始终有物品。