C语言 实现信号量版本的生产者与消费者模型
时间: 2023-10-28 08:05:52 浏览: 106
用C语言模拟生产者消费者问题
5星 · 资源好评率100%
好的,下面是一个简单的C语言实现信号量版本的生产者与消费者模型的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5 // 缓冲区大小
#define PRODUCER_NUM 3 // 生产者数量
#define CONSUMER_NUM 2 // 消费者数量
int buffer[BUFFER_SIZE]; // 缓冲区
int in = 0, out = 0; // 缓冲区读写指针
sem_t empty, full; // 信号量定义
void *producer(void *arg) {
int id = *(int*)arg;
while (1) {
int item = rand() % 1000; // 生产随机数
sem_wait(&empty); // P(empty)
buffer[in] = item; // 写入缓冲区
printf("producer %d produce item %d\n", id, item);
in = (in + 1) % BUFFER_SIZE; // 修改写指针
sem_post(&full); // V(full)
sleep(rand() % 3); // 休眠一段时间
}
}
void *consumer(void *arg) {
int id = *(int*)arg;
while (1) {
sem_wait(&full); // P(full)
int item = buffer[out]; // 读取缓冲区
printf("consumer %d consume item %d\n", id, item);
out = (out + 1) % BUFFER_SIZE; // 修改读指针
sem_post(&empty); // V(empty)
sleep(rand() % 3); // 休眠一段时间
}
}
int main() {
pthread_t producers[PRODUCER_NUM], consumers[CONSUMER_NUM];
int producer_ids[PRODUCER_NUM], consumer_ids[CONSUMER_NUM];
sem_init(&empty, 0, BUFFER_SIZE); // 初始化 empty 信号量
sem_init(&full, 0, 0); // 初始化 full 信号量
// 创建生产者线程
for (int i = 0; i < PRODUCER_NUM; i++) {
producer_ids[i] = i;
pthread_create(&producers[i], NULL, producer, &producer_ids[i]);
}
// 创建消费者线程
for (int i = 0; i < CONSUMER_NUM; i++) {
consumer_ids[i] = i;
pthread_create(&consumers[i], NULL, consumer, &consumer_ids[i]);
}
// 等待线程结束
for (int i = 0; i < PRODUCER_NUM; i++) {
pthread_join(producers[i], NULL);
}
for (int i = 0; i < CONSUMER_NUM; i++) {
pthread_join(consumers[i], NULL);
}
sem_destroy(&empty); // 销毁 empty 信号量
sem_destroy(&full); // 销毁 full 信号量
return 0;
}
```
在这个例子中,缓冲区是一个大小为 5 的整型数组,生产者线程随机生成一个整数并写入缓冲区,消费者线程读取缓冲区中的整数并打印出来。为了避免生产者与消费者同时访问缓冲区的问题,我们使用了两个信号量 empty 和 full。其中,empty 表示缓冲区空余的空间,初始值为 BUFFER_SIZE,每次写入缓冲区时需要执行 P(empty) 操作,即将 empty 的值减 1;full 表示缓冲区中已有的数据量,初始值为 0,每次读取缓冲区时需要执行 P(full) 操作,即将 full 的值减 1。当 empty 为 0 时,生产者线程会阻塞在 P(empty) 操作上;当 full 为 0 时,消费者线程会阻塞在 P(full) 操作上。代码中的 sleep(rand() % 3) 是为了模拟生产者和消费者的不同速度,让程序更加真实。
阅读全文