计算机操作系统模拟生产者-消费者问题和读者-写者问题
时间: 2024-01-17 19:04:59 浏览: 87
生产者-消费者问题是一个经典的并发问题,描述了两个进程(或线程)之间的同步和通信问题。生产者进程负责生产一些物品并将它们放入一个缓冲区中,而消费者进程则从缓冲区中取出物品并将其消耗掉。该问题的关键在于确保生产者和消费者不会同时访问缓冲区,以免出现竞态条件和数据不一致的问题。
以下是一个使用信号量来解决生产者-消费者问题的示例代码:
```c++
#include <cstdio>
#include <cstdlib>
#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; // 同步信号量,表示缓冲区中已有产品的数量
pthread_mutex_t mutex; // 互斥锁,保护对缓冲区的访问
void *producer(void *arg) {
for (int i = 0; i < 100; i++) {
sem_wait(&empty);
pthread_mutex_lock(&mutex);
buffer[in] = rand() % 100;
printf("Producer produces item %d: %d\n", in, buffer[in]);
in = (in + 1) % BUFFER_SIZE;
pthread_mutex_unlock(&mutex);
sem_post(&full);
}
}
void *consumer(void *arg) {
for (int i = 0; i < 100; i++) {
sem_wait(&full);
pthread_mutex_lock(&mutex);
int item = buffer[out];
printf("Consumer consumes item %d: %d\n", out, item);
out = (out + 1) % BUFFER_SIZE;
pthread_mutex_unlock(&mutex);
sem_post(&empty);
}
}
int main() {
sem_init(&empty, 0, BUFFER_SIZE); // 初始化 empty 为 BUFFER_SIZE
sem_init(&full, 0, 0); // 初始化 full 为 0
pthread_mutex_init(&mutex, NULL); // 初始化互斥锁
pthread_t producer_thread, consumer_thread;
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;
}
```
读者-写者问题也是一个经典的并发问题,描述了多个进程(或线程)之间共享一个资源的情况。在读者-写者问题中,资源可以被多个读者同时访问,但只能由一个写者访问。如果一个写者正在访问资源,那么其他所有的读者和写者都必须等待。如果一个读者正在访问资源,那么其他的读者可以同时访问,但写者必须等待所有的读者都访问完毕后才能访问。
以下是一个使用互斥锁和条件变量来解决读者-写者问题的示例代码:
```c++
#include <cstdio>
#include <cstdlib>
#include <pthread.h>
#define READERS_COUNT 5
#define WRITERS_COUNT 3
int read_count = 0; // 当前正在读取资源的读者数量
int resource = 0; // 被读取和写入的共享资源
pthread_mutex_t read_mutex; // 保护 read_count 的互斥锁
pthread_mutex_t write_mutex; // 保护 resource 的互斥锁
pthread_cond_t write_cond; // 写者等待的条件变量
pthread_cond_t read_cond; // 读者等待的条件变量
void *reader(void *arg) {
int id = *(int *) arg;
while (true) {
pthread_mutex_lock(&read_mutex);
read_count++;
if (read_count == 1) {
pthread_mutex_lock(&write_mutex);
}
pthread_mutex_unlock(&read_mutex);
printf("Reader %d reads resource: %d\n", id, resource);
pthread_mutex_lock(&read_mutex);
read_count--;
if (read_count == 0) {
pthread_mutex_unlock(&write_mutex);
}
pthread_mutex_unlock(&read_mutex);
sleep(rand() % 3);
}
}
void *writer(void *arg) {
int id = *(int *) arg;
while (true) {
pthread_mutex_lock(&write_mutex);
while (read_count > 0) {
pthread_cond_wait(&write_cond, &write_mutex);
}
resource = rand() % 100;
printf("Writer %d writes resource: %d\n", id, resource);
pthread_cond_broadcast(&read_cond);
pthread_mutex_unlock(&write_mutex);
sleep(rand() % 3);
}
}
int main() {
pthread_mutex_init(&read_mutex, NULL);
pthread_mutex_init(&write_mutex, NULL);
pthread_cond_init(&read_cond, NULL);
pthread_cond_init(&write_cond, NULL);
pthread_t readers[READERS_COUNT], writers[WRITERS_COUNT];
int reader_ids[READERS_COUNT], writer_ids[WRITERS_COUNT];
for (int i = 0; i < READERS_COUNT; i++) {
reader_ids[i] = i + 1;
pthread_create(&readers[i], NULL, reader, &reader_ids[i]);
}
for (int i = 0; i < WRITERS_COUNT; i++) {
writer_ids[i] = i + 1;
pthread_create(&writers[i], NULL, writer, &writer_ids[i]);
}
for (int i = 0; i < READERS_COUNT; i++) {
pthread_join(readers[i], NULL);
}
for (int i = 0; i < WRITERS_COUNT; i++) {
pthread_join(writers[i], NULL);
}
pthread_mutex_destroy(&read_mutex);
pthread_mutex_destroy(&write_mutex);
pthread_cond_destroy(&read_cond);
pthread_cond_destroy(&write_cond);
return 0;
}
```
阅读全文