当前位置:文档之家› 进程(线程)的同步与互斥实验报告

进程(线程)的同步与互斥实验报告

操作系统实验报告课程名称操作系统实验名称进程(线程)的同步与互斥成绩学生姓名作业君专业软件工程班级、学号同组者姓名无实验日期2020一、实验题目:进程(线程)的同步与互斥二、实验目的:自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。

1.掌握基本的同步与互斥算法,理解生产者消费者模型。

2.学习使用Windows中基本的同步对象,掌握相关API的使用方法。

3.了解Windows中多线程的并发执行机制,实现进程的同步与互斥三、实验内容与要求:1.实验内容以生产者/消费者模型为依据,在Windows 环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。

2.实验要求学习并理解生产者/消费者模型及其同步/互斥规则;学习了解Windows同步对象及其特性;熟悉实验环境,掌握相关API的使用方法;设计程序,实现生产者/消费者进程(线程)的同步与互斥;四、算法描述(含数据结构定义)或流程图#include <Windows.h>#include <iostream>#include <stdio.h>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;#define MAX_THREAD_NUM 64 //最大线程数#define INTE_PER_SEC 1000 //延迟时间的毫秒值const int SIZE_OF_BUFFER = 10; //缓冲区长度int ProductID = 0; //产品号int ConsumeID = 0; //将被消耗的产品号int in = 0; //产品进缓冲区时的缓冲区下标int out = 0; //产品出缓冲区时的缓冲区下标bool running = true; //判断程序能否继续执行的逻辑值int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列HANDLE g_hMutex; //公有信号量,用于线程间的互斥HANDLE g_hFullSemaphore; //生产者的私有信号量,当缓冲区满时迫使生产者等待HANDLE g_hEmptySemaphore; //消费者的私有信号量,当缓冲区空时迫使消费者等待//定义一个结构体用于存储线程的信息struct ThreadInfo{int serial; //线程号char entity; //线程类别(生产者或消费者)double delay; //等待时间double persist; //操作时间};//生产者void Producer(void* p){//定义变量用于存储当前线程的信息DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay * INTE_PER_SEC);m_persist = (DWORD)(((ThreadInfo*)(p))->persist * INTE_PER_SEC);while (running){//P操作cout << "生产者线程 " << m_serial << " 请求生产." << endl;WaitForSingleObject(g_hEmptySemaphore, INFINITE);cout << "生产者线程 " << m_serial << " 请求独占缓冲区." << endl;WaitForSingleObject(g_hMutex, INFINITE);Sleep(m_delay); //延迟等待//生产一个产品cout << "生产者线程 " << m_serial << " 生产 " << ++ProductID << " 号产品成功." << endl;cout << "生产者线程 " << m_serial << " 请求将产品 " << ProductID << " 投入缓冲区." << endl;//把新生产的产品放入缓冲区g_buffer[in] = ProductID;in = (in +1)%SIZE_OF_BUFFER;Sleep(m_persist); //操作等待cout << "生产者线程 " << m_serial << " 将产品 " << ProductID << " 投入缓冲区中成功." << endl;//输出缓冲区当前的状态cout << "****************************" << endl<< "\n当前缓冲区情况如图(■代表已有产品,□代表没有产品): " << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0) cout << "■";else cout << "□";}cout << "\n\n****************************\n" << endl;//V操作ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hFullSemaphore, 1, NULL);}}//消费者void Consumer(void* p){DWORD m_delay;DWORD m_persist;int m_serial;//从参数中获得信息m_serial = ((ThreadInfo*)(p))->serial;m_delay = (DWORD)(((ThreadInfo*)(p))->delay * INTE_PER_SEC);m_persist = (DWORD)(((ThreadInfo*)(p))->persist * INTE_PER_SEC);while (running){//P操作cout << "消费者线程 " << m_serial << " 请求消费." << endl;WaitForSingleObject(g_hFullSemaphore, INFINITE);cout << "消费者线程 " << m_serial << " 请求独占缓冲区." << endl;WaitForSingleObject(g_hMutex,INFINITE);Sleep(m_delay); //延迟等待//从缓冲区中取出一个产品cout << "消费者线程 " << m_serial << " 请求取出一个产品." << endl;ConsumeID = g_buffer[out];g_buffer[out] = 0;out = (out + 1) % SIZE_OF_BUFFER;cout << "消费者线程 " << m_serial << " 取出产品 " << ConsumeID << " 成功." << endl;//消耗一个产品cout << "消费者线程 " << m_serial << " 开始消费消费产品 " << ConsumeID << "." << endl;Sleep(m_persist);cout << "消费者线程 " << m_serial << " 消费产品 " << ConsumeID << " 成功." << endl;//输出缓冲区当前的状态cout << "****************************" << endl<< "\n当前缓冲区情况如图: " << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << "■";else cout << "□";}cout << "\n\n****************************\n" << endl;//V操作ReleaseMutex(g_hMutex);ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);}}void prod_cons(){//创建互斥信号量g_hMutex = CreateMutex(NULL, FALSE, NULL);//创建同步信号量g_hEmptySemaphore = CreateSemaphore(NULL, SIZE_OF_BUFFER, SIZE_OF_BUFFER, NULL);g_hFullSemaphore = CreateSemaphore(NULL, 0, SIZE_OF_BUFFER, NULL);srand((unsigned)time(NULL)); //以时间函数为种子const unsigned short THREADS_COUNT = rand() % 5 + 5; //总的线程数(随机生成)//线程对象的数组HANDLE hThreads[MAX_THREAD_NUM];ThreadInfo thread_info[MAX_THREAD_NUM];DWORD thread_ID; //线程IDint num = 0; //临时变量,用于循环语句cout << "系统开始模拟,并自动生成模拟数据..." << endl;system("pause"); //暂停确认开始执行cout << "线程总数:" << THREADS_COUNT << endl;//循环随机生成各个线程的信息while (num != THREADS_COUNT){thread_info[num].serial = num + 1;if (rand() % 2 == 1)thread_info[num].entity = 'P';elsethread_info[num].entity = 'C';thread_info[num].delay = rand() % 5 + 1;thread_info[num].persist = rand() % 6 + 2;num++;}cout << "\n系统生成数据结束,模拟数据如下:" << endl<< "线程号线程类别延迟时间操作时间" << endl;for (int x = 0;x < THREADS_COUNT;x++)cout << " " << thread_info[x].serial << "\t"<< " " << thread_info[x].entity << "\t"<< " " << thread_info[x].delay << "\t\t"<< " " << thread_info[x].persist << endl;cout << "\n\n==================生产者-消费者开始==================\n" << endl;//创建线程for (int i = 0;i < THREADS_COUNT;i++){//创建生产者线程if (thread_info[i].entity == 'P')hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Producer), &thread_info[i], 0, &thread_ID);//创建消费者线程elsehThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Consumer), &thread_info[i], 0, &thread_ID);}while (running){if (getchar()){//按回车后终止程序运行running = false;}}cout << "系统模拟结束..." << endl;}int main(){cout << "\n==================生产者-消费者模拟==================\n" << endl;prod_cons();}五、实验过程1、记录生产者和消费者的同步执行过程。

相关主题