Copyright © 2024 Squareroot_2, All rights reserved.
实验二 生产者消费者问题
一、实验目的
通过本实验,加深对进程概念的理解,明确进程与程序的区别;认识并发执行的本质,理解和掌握Windows进程通信系统调用的功能,通过实验掌握使用信号量机制完成进程间同步和互斥的方法。
二、实验内容
• 创建一个有6个缓冲区的缓冲池,初始为空,每个缓冲区能存放一个长度若为10个字符的字符串。
• 2个生产者进程
– 随机等待一段时间,往缓冲区添加数据,
– 若缓冲区已满,等待消费者取走数据后再添加
– 重复12次
• 3个消费者进程
– 随机等待一段时间,从缓冲区读取数据
– 若缓冲区为空,等待生产者添加数据后再读取
– 重复8次
• 在Windows平台上做。
• 显示每次添加或读取数据的时间及缓冲区的映像。
• 生产者和消费者用进程模拟。
三、程序设计与实现
#include <iostream>
#include <windows.h>
#define BUFSIZE 6 //缓冲区大小
#define STRLEN 10 //字符串长度
#define PRO_TYPE 0 //生产者标识
#define PROERNUM 2 //生产者数量
#define PRONUM 12 //每个生产者生产的数据量
#define CON_TYPE 1 //消费者标识
#define CONERNUM 3 //消费者数量
#define CONNUM 8 //每个消费者消费的数据量
static LPCTSTR filemapping_name = "FileMapping";
HANDLE ProcessHandle[5];
using namespace std;
//缓存结构体
typedef struct BUF {
char buf[BUFSIZE][STRLEN + 1];
int head;
int tail;
} buffer;
//返回随机休眠时间
int getRandomSleep() {
return rand() % 1000 + 100;
}
//返回随机字符
char getRandomChar() {
return (rand() % 26) + 'A';
}
//定义P操作
DWORD P(HANDLE S) {
return WaitForSingleObject(S, INFINITE);
}
//定义V操作
BOOL V(HANDLE S) {
return ReleaseSemaphore(S, 1, nullptr);
}
//创建子进程
void startChildProcess(const int type, const int id) {
TCHAR filename[MAX_PATH];
GetModuleFileName(nullptr, filename, MAX_PATH);
TCHAR cmdLine[MAX_PATH];
sprintf(cmdLine, "\"%s\" %d", filename, type);
STARTUPINFO si = {
sizeof(STARTUPINFO