进程线程同步和互斥实验报告.docx
《进程线程同步和互斥实验报告.docx》由会员分享,可在线阅读,更多相关《进程线程同步和互斥实验报告.docx(10页珍藏版)》请在冰豆网上搜索。
进程线程同步和互斥实验报告
进程(线程)同步和互斥实验报告
操作系统实验报告课程名称
操作系统
实验名称
进程(线程)的同步与互斥
成绩
学生姓名
作业君
专业
软件工程
班级、学号
同组者姓名
无
实验日期
2021
一、实验
题目:
:
进程(线程)的同步与互斥二、实验目的:
自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。
1.掌握基本的同步与互斥算法,理解生产者消费者模型。
2.学习使用Windows中基本的同步对象,掌握相关API的使用方法。
3.了解Windows中多线程的并发执行机制,实现进程的同步与互斥三、实验内容与要求:
1.实验内容以生产者/消费者模型为依据,在Windows环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
2.实验要求学习并理解生产者/消费者模型及其同步/互斥规则;学习了解Windows同步对象及其特性;熟悉实验环境,掌握相关API的使用方法;设计程序,实现生产者/消费者进程(线程)的同步与互斥; 四、算法描述(含数据结构定义)或流程图
#include#include#include#include#include#includeusingnamespacestd;
#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操作颠倒次序执行,程序会产生死锁。
因为这个操作会先独占缓冲区的资源,然后才发送请求。
如果生产或者消费请求无法通过而一直等待下去的话,则无法释放资源,进而产生程序的死锁,使得程序无法运行!
六、实验总结
通过本次实验,让我对线程的同步与互斥技术有了比较深刻的了解,生产者消费者问题是研究多线线程程序绕不开的问题,它的描述是有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品,这个过程可以无休止的进行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止。