进程同步实验,用C++模拟几个进程的执行过程,并使用信号量解决生产者-消费者问题,需要代码注释,100行左右的代码
时间: 2023-09-30 19:10:37 浏览: 221
以下是一个基于信号量的生产者-消费者问题的C++代码,注释已经添加在代码中。
```c++
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#define BUFFER_SIZE 10 // 缓冲区大小
#define PRODUCER_NUM 3 // 生产者数量
#define CONSUMER_NUM 2 // 消费者数量
int buffer[BUFFER_SIZE]; // 缓冲区
int in = 0; // 缓冲区写入位置
int out = 0; // 缓冲区读取位置
sem_t empty; // 缓冲区空槽数量
sem_t full; // 缓冲区满槽数量
sem_t lock; // 互斥锁
void *producer(void *arg) {
int id = *(int *)arg;
int item = 0;
while (true) {
// 产生新产品
item = rand() % 1000;
std::cout << "Producer " << id << " produced item " << item << std::endl;
// 生产者等待空槽位
sem_wait(&empty);
// 获取互斥锁
sem_wait(&lock);
// 将产品添加到缓冲区中
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
// 释放互斥锁
sem_post(&lock);
// 通知消费者可以消费了
sem_post(&full);
}
}
void *consumer(void *arg) {
int id = *(int *)arg;
int item = 0;
while (true) {
// 消费者等待满槽位
sem_wait(&full);
// 获取互斥锁
sem_wait(&lock);
// 从缓冲区中取出产品
item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
// 释放互斥锁
sem_post(&lock);
// 通知生产者可以继续生产了
sem_post(&empty);
// 消费产品
std::cout << "Consumer " << id << " consumed item " << item << std::endl;
}
}
int main() {
// 初始化信号量
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
sem_init(&lock, 0, 1);
// 创建生产者线程
pthread_t producers[PRODUCER_NUM];
int producer_ids[PRODUCER_NUM];
for (int i = 0; i < PRODUCER_NUM; i++) {
producer_ids[i] = i + 1;
pthread_create(&producers[i], NULL, producer, &producer_ids[i]);
}
// 创建消费者线程
pthread_t consumers[CONSUMER_NUM];
int consumer_ids[CONSUMER_NUM];
for (int i = 0; i < CONSUMER_NUM; i++) {
consumer_ids[i] = i + 1;
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(&empty);
sem_destroy(&full);
sem_destroy(&lock);
return 0;
}
```
以上代码中,生产者和消费者通过信号量进行进程同步,保证了缓冲区的正确访问顺序。其中,`sem_wait()` 函数会阻塞当前线程,直到信号量的值大于0,并将信号量的值减1;`sem_post()` 函数会将信号量的值加1,并唤醒正在等待该信号量的线程。`sem_init()` 函数用于初始化信号量,`sem_destroy()` 函数用于销毁信号量。
阅读全文