进程同步与互斥---生产者消费者模型
时间: 2023-06-18 11:07:47 浏览: 207
生产者消费者模型是计算机科学中一个经典的问题,也是进程同步与互斥的一个重要应用。该模型描述了一个生产者和一个消费者共同使用一个有限缓冲区的情景,生产者向缓冲区中添加数据,而消费者则从缓冲区中取出数据。
为了避免在共享缓冲区时产生数据不一致的情况,需要进行进程同步和互斥。其中,进程同步是指在多个进程之间协调事件发生的时间,而互斥则是指在同一时间只允许一个进程访问共享资源。
以下是一个基于信号量的生产者消费者模型的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE]; // 缓冲区
int in = 0; // 生产者写入数据的位置
int out = 0; // 消费者读取数据的位置
sem_t empty; // 信号量,表示缓冲区中空余的位置数
sem_t full; // 信号量,表示缓冲区中已有数据的位置数
sem_t mutex; // 信号量,用于实现互斥访问缓冲区
void *producer(void *arg)
{
int item;
while(1)
{
item = rand() % 1000; // 生产者随机生成一个数据项
sem_wait(&empty); // 等待缓冲区有空余位置
sem_wait(&mutex); // 进入互斥区,保证对缓冲区的访问是互斥的
buffer[in] = item;
printf("Producer produces item %d at buffer[%d]\n", item, in);
in = (in + 1) % BUFFER_SIZE;
sem_post(&mutex); // 退出互斥区
sem_post(&full); // 增加已有数据的位置数
sleep(rand() % 2); // 生产者随机休眠一段时间
}
}
void *consumer(void *arg)
{
int item;
while(1)
{
sem_wait(&full); // 等待缓冲区有数据
sem_wait(&mutex); // 进入互斥区
item = buffer[out];
printf("Consumer consumes item %d from buffer[%d]\n", item, out);
out = (out + 1) % BUFFER_SIZE;
sem_post(&mutex); // 退出互斥区
sem_post(&empty); // 增加空余位置数
sleep(rand() % 2); // 消费者随机休眠一段时间
}
}
int main()
{
pthread_t producer_thread, consumer_thread;
sem_init(&empty, 0, BUFFER_SIZE); // 初始化信号量
sem_init(&full, 0, 0);
sem_init(&mutex, 0, 1);
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);
sem_destroy(&mutex);
return 0;
}
```
在上述代码中,empty 表示缓冲区中空余的位置数,初始值为 BUFFER_SIZE;full 表示缓冲区中已有数据的位置数,初始值为 0;mutex 用于实现互斥访问缓冲区,初始值为 1。在生产者和消费者访问缓冲区时,都需要先进行信号量操作,保证进程同步和互斥。其中,sem_wait 和 sem_post 分别表示等待和增加信号量的值。
阅读全文