进程(线程)同步和互斥实验报告.docx

上传人:PIYPING 文档编号:13233069 上传时间:2021-12-19 格式:DOCX 页数:13 大小:15.54KB
返回 下载 相关 举报
进程(线程)同步和互斥实验报告.docx_第1页
第1页 / 共13页
进程(线程)同步和互斥实验报告.docx_第2页
第2页 / 共13页
进程(线程)同步和互斥实验报告.docx_第3页
第3页 / 共13页
进程(线程)同步和互斥实验报告.docx_第4页
第4页 / 共13页
亲,该文档总共13页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《进程(线程)同步和互斥实验报告.docx》由会员分享,可在线阅读,更多相关《进程(线程)同步和互斥实验报告.docx(13页珍藏版)》请在三一文库上搜索。

1、进程(线程)同步和互斥实验报告 操 作 系 统 实 验 报 告 课程名称 操作系统 实验名称 进程(线程)的同步与互斥 成绩 学生姓名 作业君 专业 软件工程 班级、学号 同组者姓名 无 实验日期 2021 一、实验题目: : 进程(线程)的同步与互斥 二、实验目的 : 自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的 PCB 内容 、组织的变化,理解进程与其 PCB 间的一一对应关系。 1掌握基本的同步与互斥算法,理解生产者消费者模型。 2学习使用 Windows 中基本的同步对象,掌握相关 API 的使用方法。 3了解 Windows 中多线程的并

2、发执行机制,实现进程的同步与互斥 三、实验内容与要求 : 1实验内容 以生产者/消费者模型为依据,在 Windows 环境下创建一个控制台进程,在该进程中创建 n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。 2实验要求 学习并理解生产者/消费者模型及其同步/互斥规则; 学习了解 Windows 同步对象及其特性; 熟悉实验环境,掌握相关 API 的使用方法; 设计程序,实现生产者/消费者进程(线程)的同步与互斥; 四、算法描述(含数据结构定义)或流程图 #include Windows.h #include iostream #include stdio.h #include m

3、ath.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; /判断

4、程序能否继续执行的逻辑值 int g_bufferSIZE_OF_BUFFER; /缓冲区是个循环队列 HANDLE g_hMutex; /公有信号量,用于线程间的互斥 HANDLE g_hFullSemaphore; /生产者的私有信号量,当缓冲区满时迫使生产者等待 HANDLE g_hEmptySemaphore; /消费者的私有信号量,当缓冲区空时迫使消费者等待 /定义一个结构体用于存储线程的信息 struct ThreadInfo int serial; /线程号 char entity; /线程类别(生产者或消费者) double delay; /等待时间 double persis

5、t; /操作时间 ; /生产者 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

6、_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_bufferin = P

7、roductID; 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_bufferi != 0) cout ; else cout ; cout nn*n endl; /V 操作 ReleaseMutex(g_hMutex); ReleaseS

8、emaphore(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 操作 cou

9、t 消费者线程 m_serial 请求消费. endl; WaitForSingleObject(g_hFullSemaphore, INFINITE); cout 消费者线程 m_serial 请求独占缓冲区. endl; WaitForSingleObject(g_hMutex,INFINITE); Sleep(m_delay); /延迟等待 /从缓冲区中取出一个产品 cout 消费者线程 m_serial 请求取出一个产品. endl; ConsumeID = g_bufferout; g_bufferout = 0; out = (out + 1) % SIZE_OF_BUFFER;

10、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_bufferi != 0) cout ; else cout ; cout nn*n endl; /V

11、操作 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); s

12、rand(unsigned)time(NULL); /以时间函数为种子 const unsigned short THREADS_COUNT = rand() % 5 + 5; /总的线程数(随机生成) /线程对象的数组 HANDLE hThreadsMAX_THREAD_NUM; ThreadInfo thread_infoMAX_THREAD_NUM; DWORD thread_ID; /线程 ID int num = 0; /临时变量,用于循环语句 cout 系统开始模拟,并自动生成模拟数据. endl; system(pause); /暂停确认开始执行 cout 线程总数: THREA

13、DS_COUNT endl; /循环随机生成各个线程的信息 while (num != THREADS_COUNT) thread_infonum.serial = num + 1; if (rand() % 2 = 1) thread_infonum.entity = "P" else thread_infonum.entity = "C" thread_infonum.delay = rand() % 5 + 1; thread_infonum.persist = rand() % 6 + 2; num+; cout n 系统生成数据结束,模拟数据如

14、下: endl 线程号 线程类别 延迟时间 操作时间 endl; for (int x = 0;x THREADS_COUNT;x+) cout thread_infox.serial t thread_infox.entity t thread_infox.delay tt thread_infox.persist endl; cout nn=生产者-消费者 开始=n endl; /创建线程 for (int i = 0;i THREADS_COUNT;i+) /创建生产者线程 if (thread_infoi.entity = "P") hThreadsi = Crea

15、teThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Producer), thread_infoi, 0, thread_ID); /创建消费者线程 else hThreadsi = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Consumer), thread_infoi, 0, thread_ID); while (running) if (getchar() /按回车后终止程序运行 running = false; cout 系统模拟结束. endl; int main() cout n=生产者-消费者

16、模拟=n endl; prod_cons(); 五、实验过程 1、记录生产者和消费者的同步执行过程。 2、分析 Producer 函数和 Consumer 函数的功能,并画出对应的程序流程图。 Producer 函数:调用函数,获取资源情况,然后判断条件是否满足,判断是否执行,接着发出生产请求,请求通过后独占缓冲区资源,接着生产-一个产品投入缓冲区,成功后释放所占缓冲区资源,到此此函数执行完成。 consumer 函数: 通过用变量提取保存提取当前资源信息, 然后判断是否执行, 接着发出消费请求, 请求通过后独占缓冲区资源, 接着消费一个产品取出缓冲区, 成功后释放所占缓冲区资源, 到此此函数

17、执行完成。 3、试将同步和互斥的 P 操作颠倒次序执行,观察并分析程序的运行情况。 答: 如将同步和互斥的 P 操作颠倒次序执行,程序会产生死锁。因为这个操作会先独占缓冲区的资源,然后才发送请求。如果生产或者消费请求无法通过而一直等待下去的话,则无法释放资源,进而产生程序的死锁,使得程序无法运行! 六、实验总结 通过本次实验,让我对线程的同步与互斥技术有了比较深刻的了解,生产者消费者问题是研究多线线程程序绕不开的问题,它的描述是有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品,这个过程可以无休止的进行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 科普知识


经营许可证编号:宁ICP备18001539号-1