在linux下用C语言简单的实现信号量机制模拟实现生产者-消费者问题
时间: 2023-06-14 14:05:52 浏览: 149
计算机操作系统 利用信号量机制模拟 生产者与消费者问题
4星 · 用户满意度95%
信号量是一种同步机制,用于在多个进程或线程之间协调共享资源的使用。生产者-消费者问题是一个经典的同步问题,其中生产者进程生成数据并将其放入缓冲区,而消费者进程从缓冲区中获取数据并将其消耗掉。为了避免竞争条件和死锁,需要使用信号量来控制对共享缓冲区的访问。
下面是一个简单的实现,其中使用了 POSIX 信号量和线程库。
```
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE]; // 缓冲区
int buffer_index = 0; // 缓冲区当前索引
sem_t empty; // 空闲缓冲区信号量
sem_t full; // 已占用缓冲区信号量
pthread_mutex_t mutex; // 互斥锁
void *producer(void *arg) {
int item;
while (1) {
item = rand() % 1000; // 随机生成一个数据项
sem_wait(&empty); // 等待空闲缓冲区
pthread_mutex_lock(&mutex); // 加锁
buffer[buffer_index] = item;
buffer_index++;
printf("Produced item: %d\n", item);
pthread_mutex_unlock(&mutex); // 解锁
sem_post(&full); // 发布已占用缓冲区
}
}
void *consumer(void *arg) {
int item;
while (1) {
sem_wait(&full); // 等待已占用缓冲区
pthread_mutex_lock(&mutex); // 加锁
buffer_index--;
item = buffer[buffer_index];
printf("Consumed item: %d\n", item);
pthread_mutex_unlock(&mutex); // 解锁
sem_post(&empty); // 发布空闲缓冲区
}
}
int main() {
pthread_t producer_thread, consumer_thread;
sem_init(&empty, 0, BUFFER_SIZE); // 初始化空闲缓冲区信号量
sem_init(&full, 0, 0); // 初始化已占用缓冲区信号量
pthread_mutex_init(&mutex, NULL); // 初始化互斥锁
pthread_create(&producer_thread, NULL, producer, NULL); // 创建生产者线程
pthread_create(&consumer_thread, NULL, consumer, NULL); // 创建消费者线程
pthread_join(producer_thread, NULL); // 等待生产者线程结束
pthread_join(consumer_thread, NULL); // 等待消费者线程结束
sem_destroy(&empty); // 销毁空闲缓冲区信号量
sem_destroy(&full); // 销毁已占用缓冲区信号量
pthread_mutex_destroy(&mutex); // 销毁互斥锁
return 0;
}
```
在上面的代码中,我们使用了两个信号量 `empty` 和 `full` 来控制缓冲区的空闲和已占用状态。生产者线程在生产一个数据项后会等待 `empty` 信号量,如果缓冲区已满则会被阻塞。消费者线程在消费一个数据项后会等待 `full` 信号量,如果缓冲区为空则会被阻塞。同时,我们使用了一个互斥锁 `mutex` 来保证对缓冲区的访问是互斥的,避免竞争条件。
需要注意的是,上面的代码仅仅是一个简单的实现,实际使用中还需要考虑许多其他因素,例如如何处理异常情况、如何优化性能等等。
阅读全文