信号量实现生产者消费者C语言
时间: 2023-08-20 22:19:40 浏览: 22
以下是使用信号量实现生产者消费者问题的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 5 // 缓冲池大小
#define PRODUCER_NUM 2 // 生产者数量
#define CONSUMER_NUM 3 // 消费者数量
#define ITEM_COUNT 20 // 生产/消费总数
int buffer[BUFFER_SIZE]; // 缓冲池
int in = 0; // 生产者写入位置
int out = 0; // 消费者读取位置
sem_t mutex; // 互斥信号量,保护缓冲池的访问
sem_t empty; // 空闲信号量,表示缓冲池空闲位置数量
sem_t full; // 满信号量,表示缓冲池已有数据数量
void* producer(void* arg) {
int id = *(int*)arg;
for (int i = 0; i < ITEM_COUNT; i++) {
sem_wait(&empty); // 等待空闲空间
sem_wait(&mutex); // 互斥访问缓冲池
buffer[in] = i;
printf("Producer %d: produced item %d at buffer[%d]\n", id, i, in);
in = (in + 1) % BUFFER_SIZE;
sem_post(&mutex); // 释放互斥信号量
sem_post(&full); // 发送满信号量
}
return NULL;
}
void* consumer(void* arg) {
int id = *(int*)arg;
for (int i = 0; i < ITEM_COUNT / CONSUMER_NUM; i++) {
sem_wait(&full); // 等待缓冲池有数据
sem_wait(&mutex); // 互斥访问缓冲池
int item = buffer[out];
printf("Consumer %d: consumed item %d at buffer[%d]\n", id, item, out);
out = (out + 1) % BUFFER_SIZE;
sem_post(&mutex); // 释放互斥信号量
sem_post(&empty); // 发送空闲信号量
}
return NULL;
}
int main() {
sem_init(&mutex, 0, 1); // 初始化互斥信号量
sem_init(&empty, 0, BUFFER_SIZE); // 初始化空闲信号量
sem_init(&full, 0, 0); // 初始化满信号量
pthread_t producers[PRODUCER_NUM];
pthread_t consumers[CONSUMER_NUM];
int producer_ids[PRODUCER_NUM];
int consumer_ids[CONSUMER_NUM];
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(&mutex);
sem_destroy(&empty);
sem_destroy(&full);
return 0;
}
```
在这个程序中,我们使用了三个信号量:互斥信号量 `mutex` 用于保护缓冲池的访问,空闲信号量 `empty` 表示缓冲池空闲位置数量,满信号量 `full` 表示缓冲池已有数据数量。
生产者线程的主要操作是往缓冲池中写入数据。当缓冲池已满时,生产者需要等待空闲信号量 `empty`;当生产者向缓冲池中写入数据时,需要先获得互斥信号量 `mutex`,以保证缓冲池的访问不会发生冲突。
消费者线程的主要操作是从缓冲池中读取数据。当缓冲池为空时,消费者需要等待满信号量 `full`;当消费者从缓冲池中读取数据时,也需要先获得互斥信号量 `mutex`。
在 `main` 函数中,我们首先初始化三个信号量,然后创建多个生产者和消费者线程。当所有生产者和消费者线程都执行完毕后,我们销毁三个信号量。
相关推荐

















