Files
OperatingSystem/ProcessSync.cpp
2025-11-06 10:36:22 +08:00

186 lines
6.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <iostream>
#include <thread>
#include <vector>
#include <chrono>
#include <random>
#include <semaphore>
#include <mutex>
#include <iomanip>
using namespace std;
// 缓冲区大小
const int BUFFER_SIZE = 5;
// 生产者数量
const int PRODUCER_COUNT = 3;
// 消费者数量
const int CONSUMER_COUNT = 2;
// 每个生产者生产的产品数量
const int PRODUCTS_PER_PRODUCER = 10;
// 缓冲区结构
struct Buffer {
vector<int> data; // 存储产品的数组
int in; // 生产者插入位置
int out; // 消费者取出位置
Buffer() : data(BUFFER_SIZE, 0), in(0), out(0) {}
};
// 全局变量
Buffer buffer; // 共享缓冲区
counting_semaphore<BUFFER_SIZE> empty_sem(BUFFER_SIZE); // 空缓冲区数量信号量
counting_semaphore<BUFFER_SIZE> full_sem(0); // 满缓冲区数量信号量
mutex buffer_mutex; // 缓冲区互斥锁
mutex output_mutex; // 输出互斥锁
int total_produced = 0; // 总生产数量
int total_consumed = 0; // 总消费数量
// 打印缓冲区状态的函数
void print_buffer_status(const string& operation, int thread_id, int product_id) {
lock_guard<mutex> lock(output_mutex);
cout << operation << " 线程" << thread_id << " 产品" << product_id << endl;
cout << "缓冲区状态: [";
for (int i = 0; i < BUFFER_SIZE; i++) {
if (i > 0) cout << ", ";
if ((buffer.out <= buffer.in && i >= buffer.out && i < buffer.in) ||
(buffer.out > buffer.in && (i >= buffer.out || i < buffer.in))) {
cout << buffer.data[i];
} else {
cout << "";
}
}
cout << "]" << endl;
cout << "in=" << buffer.in << ", out=" << buffer.out;
cout << ", 已生产=" << total_produced << ", 已消费=" << total_consumed << endl;
cout << "----------------------------------------" << endl;
}
// 生产者函数
void producer(int producer_id) {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dis(100, 999); // 生成三位数产品编号
for (int i = 0; i < PRODUCTS_PER_PRODUCER; i++) {
// 生产产品(模拟生产时间)
this_thread::sleep_for(chrono::milliseconds(dis(gen) % 500 + 100));
int product = producer_id * 1000 + i + 1; // 产品编号生产者ID*1000 + 序号
// P操作等待空缓冲区
empty_sem.acquire();
// P操作获取缓冲区互斥锁
{
lock_guard<mutex> lock(buffer_mutex);
// 将产品放入缓冲区
buffer.data[buffer.in] = product;
buffer.in = (buffer.in + 1) % BUFFER_SIZE;
total_produced++;
// 打印生产信息
print_buffer_status("生产者", producer_id, product);
}
// V操作释放满缓冲区信号量
full_sem.release();
}
{
lock_guard<mutex> lock(output_mutex);
cout << "生产者" << producer_id << " 完成所有生产任务" << endl;
}
}
// 消费者函数
void consumer(int consumer_id) {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dis(100, 999);
// 计算每个消费者需要消费的产品数量
int products_to_consume = (PRODUCER_COUNT * PRODUCTS_PER_PRODUCER) / CONSUMER_COUNT;
if (consumer_id < (PRODUCER_COUNT * PRODUCTS_PER_PRODUCER) % CONSUMER_COUNT) {
products_to_consume++; // 处理不能整除的情况
}
for (int i = 0; i < products_to_consume; i++) {
// P操作等待满缓冲区
full_sem.acquire();
int product;
// P操作获取缓冲区互斥锁
{
lock_guard<mutex> lock(buffer_mutex);
// 从缓冲区取出产品
product = buffer.data[buffer.out];
buffer.data[buffer.out] = 0; // 清空该位置
buffer.out = (buffer.out + 1) % BUFFER_SIZE;
total_consumed++;
// 打印消费信息
print_buffer_status("消费者", consumer_id, product);
}
// V操作释放空缓冲区信号量
empty_sem.release();
// 消费产品(模拟消费时间)
this_thread::sleep_for(chrono::milliseconds(dis(gen) % 300 + 150));
}
{
lock_guard<mutex> lock(output_mutex);
cout << "消费者" << consumer_id << " 完成所有消费任务" << endl;
}
}
int main() {
cout << "========== 多生产者多消费者多缓冲区同步实验 ==========" << endl;
cout << "缓冲区大小: " << BUFFER_SIZE << endl;
cout << "生产者数量: " << PRODUCER_COUNT << endl;
cout << "消费者数量: " << CONSUMER_COUNT << endl;
cout << "每个生产者生产产品数: " << PRODUCTS_PER_PRODUCER << endl;
cout << "总产品数量: " << PRODUCER_COUNT * PRODUCTS_PER_PRODUCER << endl;
cout << "========================================" << endl;
// 创建生产者线程
vector<thread> producers;
for (int i = 0; i < PRODUCER_COUNT; i++) {
producers.emplace_back(producer, i + 1);
}
// 创建消费者线程
vector<thread> consumers;
for (int i = 0; i < CONSUMER_COUNT; i++) {
consumers.emplace_back(consumer, i + 1);
}
// 等待所有生产者线程结束
for (auto& p : producers) {
p.join();
}
// 等待所有消费者线程结束
for (auto& c : consumers) {
c.join();
}
cout << "========== 实验结束 ==========" << endl;
cout << "最终统计:" << endl;
cout << "总生产数量: " << total_produced << endl;
cout << "总消费数量: " << total_consumed << endl;
if (total_produced == total_consumed &&
total_produced == PRODUCER_COUNT * PRODUCTS_PER_PRODUCER) {
cout << "实验成功!所有产品都被正确生产和消费。" << endl;
} else {
cout << "实验异常!生产和消费数量不匹配。" << endl;
}
return 0;
}