进程线程同步和互斥实验报告.docx
- 文档编号:27196018
- 上传时间:2023-06-28
- 格式:DOCX
- 页数:10
- 大小:17.10KB
进程线程同步和互斥实验报告.docx
《进程线程同步和互斥实验报告.docx》由会员分享,可在线阅读,更多相关《进程线程同步和互斥实验报告.docx(10页珍藏版)》请在冰豆网上搜索。
进程线程同步和互斥实验报告
进程(线程)同步和互斥实验报告
操作系统实验报告课程名称
操作系统
实验名称
进程(线程)的同步与互斥
成绩
学生姓名
作业君
专业
软件工程
班级、学号
同组者姓名
无
实验日期
2021
一、实验
题目:
:
进程(线程)的同步与互斥二、实验目的:
自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。
1.掌握基本的同步与互斥算法,理解生产者消费者模型。
2.学习使用Windows中基本的同步对象,掌握相关API的使用方法。
3.了解Windows中多线程的并发执行机制,实现进程的同步与互斥三、实验内容与要求:
1.实验内容以生产者/消费者模型为依据,在Windows环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
2.实验要求学习并理解生产者/消费者模型及其同步/互斥规则;学习了解Windows同步对象及其特性;熟悉实验环境,掌握相关API的使用方法;设计程序,实现生产者/消费者进程(线程)的同步与互斥; 四、算法描述(含数据结构定义)或流程图
#include
#defineMA__THREAD_NUM64
//最大线程数#defineINTE_PER_SEC1000
//延迟时间的毫秒值constintSIZE_OF_BUFFER=10;
//缓冲区长度intProductID=0;
//产品号intConsumeID=0;
//将被消耗的产品号intin=0;
//产品进缓冲区时的缓冲区下标intout=0;
//产品出缓冲区时的缓冲区下标boolrunning=true;
//判断程序能否继续执行的逻辑值intg_buffer[SIZE_OF_BUFFER];
//缓冲区是个循环队列HANDLEg_hMute_;
//公有信号量,用于线程间的互斥HANDLEg_hFullSemaphore;
//生产者的私有信号量,当缓冲区满时迫使生产者等待HANDLEg_hEmptySemaphore;
//消费者的私有信号量,当缓冲区空时迫使消费者等待
//定义一个结构体用于存储线程的信息structThreadInfo{
intserial;
//线程号
charentity;
//线程类别(生产者或消费者)
doubledelay;
//等待时间
doublepersist;//操作时间};
//生产者voidProducer(void_
p){
//定义变量用于存储当前线程的信息
DWORDm_delay;
DWORDm_persist;
intm_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<<“生产者线程”< WaitForSingleObject(g_hEmptySemaphore,INFINITE); cout<<“生产者线程”< WaitForSingleObject(g_hMute_,INFINITE); Sleep(m_delay); //延迟等待 //生产一个产品 cout<<“生产者线程”< cout<<“生产者线程”< //把新生产的产品放入缓冲区 g_buffer[in]=ProductID; in=(in+1)%SIZE_OF_BUFFER; Sleep(m_persist); //操作等待 cout<<“生产者线程”< //输出缓冲区当前的状态 cout<<“____________________________”< <<“\n当前缓冲区情况如图(■代表已有产品,□代表没有产品): ”< for(inti=0;i { if(g_buffer[i]! =0) cout<<“■”; else cout<<“□”; } cout<<“\n\n____________________________\n”< //V操作 ReleaseMute_(g_hMute_); ReleaseSemaphore(g_hFullSemaphore,1,NULL); }} //消费者voidConsumer(void_ p){ DWORDm_delay; DWORDm_persist; intm_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<<“消费者线程”< WaitForSingleObject(g_hFullSemaphore,INFINITE); cout<<“消费者线程”< WaitForSingleObject(g_hMute_,INFINITE); Sleep(m_delay);//延迟等待 //从缓冲区中取出一个产品 cout<<“消费者线程”< ConsumeID=g_buffer[out]; g_buffer[out]=0; out=(out+1)%SIZE_OF_BUFFER; cout<<“消费者线程”< //消耗一个产品 cout<<“消费者线程”< Sleep(m_persist); cout<<“消费者线程”< //输出缓冲区当前的状态 cout<<“____________________________”< <<“\n当前缓冲区情况如图: ”< for(inti=0;i { if(g_buffer[i]! =0) cout<<“■”; else cout<<“□”; } cout<<“\n\n____________________________\n”< //V操作 ReleaseMute_(g_hMute_); ReleaseSemaphore(g_hEmptySemaphore,1,NULL); }} voidprod_cons{ //创建互斥信号量 g_hMute_=CreateMute_(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)); //以时间函数为种子 constunsignedshortTHREADS_COUNT=rand%5+5;//总的线程数(随机生成) //线程对象的数组 HANDLEhThreads[MA__THREAD_NUM]; ThreadInfothread_info[MA__THREAD_NUM]; DWORDthread_ID;//线程ID intnum=0; //临时变量,用于循环语句 cout<<“系统开始模拟,并自动生成模拟数据...”< system(“pause”);//暂停确认开始执行 cout<<“线程总数: ”< //循环随机生成各个线程的信息 while(num! =THREADS_COUNT) { thread_info[num].serial=num+1; if(rand%2==1) thread_info[num].entity="P"; else thread_info[num].entity="C"; thread_info[num].delay=rand%5+1; thread_info[num].persist=rand%6+2; num++; } cout<<“\n系统生成数据结束,模拟数据如下: ”< <<“线程号 线程类别 延迟时间 操作时间”< for(int_=0;_ cout<<“ ”< <<“ ”< <<“ ”< <<“ ”< cout<<“\n\n==================生产者-消费者开始==================\n”< //创建线程 for(inti=0;i { //创建生产者线程 if(thread_info[i].entity=="P") hThreads[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Producer),;thread_info[i],0,;thread_ID); //创建消费者线程 else hThreads[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consumer),;thread_info[i],0,;thread_ID); } while(running) { if(getchar) { //按回车后终止程序运行 running=false; } } cout<<“系统模拟结束...”< cout<<“\n==================生产者-消费者模拟==================\n”< prod_cons;} 五、实验过程 1、记录生产者和消费者的同步执行过程。 2、分析Producer函数和Consumer函数的功能,并画出对应的程序流程图。 Producer函数: 调用函数,获取资源情况,然后判断条件是否满足,判断是否执行,接着发出生产请求,请求通过后独占缓冲区资源,接着生产-一个产品投入缓冲区,成功后释放所占缓冲区资源,到此此函数执行完成。 consumer函数: 通过用变量提取保存提取当前资源信息,然后判断是否执行,接着发出消费请求,请求通过后独占缓冲区资源,接着消费一个产品取出缓冲区,成功后释放所占缓冲区资源,到此此函数执行完成。 3、试将同步和互斥的P操作颠倒次序执行,观察并分析程序的运行情况。 答: 如将同步和互斥的P操作颠倒次序执行,程序会产生死锁。 因为这个操作会先独占缓冲区的资源,然后才发送请求。 如果生产或者消费请求无法通过而一直等待下去的话,则无法释放资源,进而产生程序的死锁,使得程序无法运行! 六、实验总结 通过本次实验,让我对线程的同步与互斥技术有了比较深刻的了解,生产者消费者问题是研究多线线程程序绕不开的问题,它的描述是有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品,这个过程可以无休止的进行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程 线程 同步 实验 报告