生产者消费者c代码有注释的
时间: 2024-02-12 16:09:18 浏览: 70
以下是一个带有注释的C语言生产者消费者模型代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10 // 缓冲区大小为10
int buffer[BUFFER_SIZE]; // 缓冲区数组
sem_t empty; // 空信号量,表示可用缓冲区槽位数量
sem_t full; // 满信号量,表示已经被占用的缓冲区槽位数量
pthread_mutex_t mutex; // 互斥锁,用于保证线程安全访问缓冲区
int in = 0; // 生产者放置数据的位置
int out = 0; // 消费者取走数据的位置
// 生产者线程函数
void *producer(void *arg) {
int i, item;
for (i = 0; i < 10; i++) { // 生产10个数据项
item = rand(); // 生产一个随机数
sem_wait(&empty); // 等待空槽位
pthread_mutex_lock(&mutex); // 上锁
buffer[in] = item; // 将数据放入缓冲区
in = (in + 1) % BUFFER_SIZE; // 更新放置数据的位置
printf("Producer produces item %d\n", item); // 打印生产信息
pthread_mutex_unlock(&mutex); // 解锁
sem_post(&full); // 发送满槽位信号
}
pthread_exit(NULL); // 退出线程
}
// 消费者线程函数
void *consumer(void *arg) {
int i, item;
for (i = 0; i < 10; i++) { // 消费10个数据项
sem_wait(&full); // 等待满槽位
pthread_mutex_lock(&mutex); // 上锁
item = buffer[out]; // 从缓冲区取出数据
out = (out + 1) % BUFFER_SIZE; // 更新取走数据的位置
printf("Consumer consumes item %d\n", item); // 打印消费信息
pthread_mutex_unlock(&mutex); // 解锁
sem_post(&empty); // 发送空槽位信号
}
pthread_exit(NULL); // 退出线程
}
int main() {
pthread_t pid, cid; // 生产者和消费者线程ID
sem_init(&empty, 0, BUFFER_SIZE); // 初始化空信号量
sem_init(&full, 0, 0); // 初始化满信号量
pthread_mutex_init(&mutex, NULL); // 初始化互斥锁
pthread_create(&pid, NULL, producer, NULL); // 创建生产者线程
pthread_create(&cid, NULL, consumer, NULL); // 创建消费者线程
pthread_join(pid, NULL); // 等待生产者线程结束
pthread_join(cid, NULL); // 等待消费者线程结束
sem_destroy(&empty); // 销毁空信号量
sem_destroy(&full); // 销毁满信号量
pthread_mutex_destroy(&mutex); // 销毁互斥锁
return 0; // 程序结束
}
```
在这个代码中,我们使用了两个信号量 `empty` 和 `full` 来控制缓冲区的空/满状态,使用一个互斥锁 `mutex` 来保证多线程间的安全访问。在生产者和消费者线程中,我们使用 `sem_wait` 和 `sem_post` 函数来操作信号量,使用 `pthread_mutex_lock` 和 `pthread_mutex_unlock` 函数来操作互斥锁。这样就能够保证生产者和消费者之间的同步和互斥,避免了竞争条件和死锁的问题。
阅读全文