Initial commit
This commit is contained in:
185
ProcessSync.cpp
Normal file
185
ProcessSync.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user