【实验思考及总结】
Sleep(10) 使当前线程放弃目前的时间片,并且在 10ms 内不会被再次调度
进程也有父子关系。
父进程退出后子进程也会退出,线程之间的同步使用一些核心对象:
如thread, process,evnet,mutex,semaphore.在线程之间使用等待函数如WaitForSingleObjects, WaitForMultipleObjects.等待函数使用核心对象的handle作为参数,如果handle被激发,则执行下一步。
LeaveCriticalSection
2)Mutex:
适用范围:
不同线程之间用来排它性占有特性:
核心对象,可以使用wait进行等待,只能被拥有线程所释放函数:
CreateMutexReleaseMutex
3)semaphore:
信号量适用范围:
用来限制资源占用特性:
核心对象,没有拥有者,任何线程都可释放函数:
CreateSemaphoreOpenSemaphoreReleaseSemaphore
4)Event:
适用范围:
同来控制对象信号的接收,常与信号系统结合起来特性:
核心对象函数:
CreateEventOpenEventPulseEventSetEventResetEvent 5)Interlocked简单的原子操作,如写文件中对文件中字节范围的锁定_locking
NOTE:
线程同步中很重要的可归纳为锁系统lock和信号系统signallock包括:
CRITICAL_SECTION,Mutex,waitfunction:
WaitForMultipleObjectsWaitForSingleObject Sleep 6)completionport适用范围:
网络异步接收,包括文件读写特性:
由OS来控制读写,是windows平台最有效的同步机制,相当于linux的AIO或者非阻塞socket+epoll函数:
CreateIoCompletionPortGetQueuedCompletionStatus
示例1:
event事件机制:
设置一个全局event对象,这个只能等待最多64个对象,而且要用WaitForMultipleObjects来监视线
程handle数组.不如完全端口completionportHANDLEghWriteEvent;HANDLEghThreads[THREADCOUNT];
(1)创建个手动事件,一开始不接受任何信号nosignelResetEvent:
用来信号重置,同CreateEventorOpenEvent ghWriteEvent=CreateEvent( NULL, defaultsecurityattributes TRUE, manual-resetevent FALSE, initialstateisnonsignaled TEXT("WriteEvent") objectname );
(2)产生一堆线程,设置事件响应信号signal, if(!
SetEvent(ghWriteEvent)) { printf("SetEventfailed(%d)n",GetLastError()); return; }(3)设置线程等待事件,所有线程都接到这个事件,,这里对线程进行了同步,只有所有线程都执行了,才执行下一步 dwWaitResult=WaitForMultipleObjects( THREADCOUNT, numberofarray ghThreads, arrayofthreadport
(1)创建完成端口,与一个监听socket发生关联CreateIoCompletionPort
(2)产生一堆线程,让线程在完全端口循环等待.CreateThread--(WorkerThread)--
GetQueuedCompletionStatus (3)接收监听socket的读写请求accept,将acceptsocket与完全端口关联
实验三Windows线程通信
【开发语言及实现平台或实验环境】
C++C#
MicrosoftVisualStudio6.0MicrosoftVisualStudio.NET
【实验目的】
(1)了解Window线程通信方法;
(2)了解匿名管道,并通过查阅资料理解匿名管道的使用方法;
(3)了解命名管道,并通过查阅资料理解命名管道的使用方法;
【实验要求】
(1)逐程序进行简要分析、运行各程序并仔细阅读注释;
(2)查阅MSDN或其他资料,掌握相关系统调用使用方法和参数含义;
(3)完成实验报告。
【实验结果与分析】
【实验思考及总结】
学会了在vc6.0中open已经编译好的程序,选择所有文件,线程之间通信的两个基本问题是互斥和同步。
线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。
线程互斥是指对于共享的操作系统资源(指的是广义的"资源",而不是Windows的.res文件,譬如全局变量就是一种共享资源),在各线程访问时的排它性。
当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。
线程互斥是一种特殊的线程同步。
实际上,互斥和同步对应着线程间通信发生的两种情况:
(1)当有多个线程访问共享资源而不使资源被破坏时;
(2)当一个线程需要将某个任务已经完成的情况通知另外一个或多个线程时。
在WIN32中,同步机制主要有以下几种:
(1)事件(Event);
(2)信号量(semaphore);
(3)互斥量(mutex);
(4)临界区(Criticalsection)。
全局变量
因为进程中的所有线程均可以访问所有的全局变量,因而全局变量成为Win32多线程通信的最简单方式。
例如:
实验四银行家算法模拟
【开发语言及实现平台或实验环境】
C++C#
MicrosoftVisualStudio6.0MicrosoftVisualStudio.NET2003
【实验目的】
(1)进一步理解利用银行家算法避免死锁的问题;
(2)在了解和掌握银行家算法。
(3)理解和掌握安全序列、安全性算法
【实验内容】
(1)编写安全性算法;
(2)编写银行家算法,并编制银行家算法通用程序,将调试结果显示在计算机屏幕上,再检测和笔算的一致性。
【源代码】
#include
usingnamespacestd;
#includeintNeed[100][100]={0};还需要资源
intRequest[100]={0};请求资源向量
inttemp[100]={0};存放安全序列
intWork[100]={0};存放系统可提供资源
intM=100;作业的最大数为100
intN=100;资源的最大数为100
voidshowdata()显示资源矩阵
{
inti,j;
cout<<"系统目前可用的资源[Avaliable]:
"<for(i=0;icout<for(j=0;jcout<cout<<"MaxAllocationNeed"<cout<<"进程名";
for(j=0;j<3;j++){
for(i=0;icout<<"";
}
cout<for(i=0;icout<<""<
for(j=0;jcout<<"";
for(j=0;jcout<<"";
for(j=0;jcout<}
}
intchangdata(inti)进行资源分配
{
intj;
for(j=0;jAvaliable[j]=Avaliable[j]-Request[j];
Allocation[i][j]=Allocation[i][j]+Request[j];
Need[i][j]=Need[i][j]-Request[j];
}
return1;
}
intsafe()安全性算法
{
inti,k=0,m,apply,Finish[100]={0};
intj;
intflag=0;
for(i=0;i{
Work[i]=Avaliable[i];
}
for(i=0;iapply=0;
for(j=0;jif(Finish[i]==False&&Need[i][j]<=Work[j]){
apply++;
if(apply==N){
for(m=0;mFinish[i]=True;
temp[k]=i;i=-1;
k++;flag++;
}
}
}
}
for(i=0;iif(Finish[i]==False){
cout<<"系统不安全"<return-1;
}
}
cout<<"系统是安全的!
"<cout<<"分配的序列:
";
for(i=0;icout<if(i";
}
cout<return0;
}
voidshare()利用银行家算法对申请资源对进行判定
{
charch;
inti=0,j=0;
ch='y';
cout<<"请输入要求分配的资源进程号(0-"<";
cin>>i;输入须申请的资源号
cout<<"请输入进程"<
"<for(j=0;jcout<";
cin>>Request[j];输入需要申请的资源
}
for(j=0;jif(Request[j]>Need[i][j])判断申请是否大于需求,若大于则出错
{
cout<<"进程"<
cout<<"分配不合理,不予分配!
"<ch='n';
break;
}
else{
if(Request[j]>Avaliable[j])判断申请是否大于当前资源,若大于则
{
出错
cout<<"进程"<
cout<<"分配出错,不予分配!
"<ch='n';
break;
}
}
}
if(ch=='y'){
changdata(i);根据进程需求量变换资源
showdata();根据进程需求量显示变换后的资源
safe();根据进程需求量进行银行家算法判断
}
}
voidaddresources(){添加资源
intn,flag;
cout<<"请输入需要添加资源种类的数量:
";
cin>>n;
flag=N;
N=N+n;
for(inti=0;icout<<"名称:
";
cin>>name[flag];
cout<<"数量:
";
cin>>Avaliable[flag++];
}
showdata();
safe();
}
voiddelresources(){删除资源
charming;
inti,flag=1;
cout<<"请输入需要删除的资源名称:
";
do{
cin>>ming;
for(i=0;iif(ming==name[i]){
flag=0;
break;
}
if(i==N)
cout<<"该资源名称不存在,请重新输入:
";
}
while(flag);
for(intj=i;jname[j]=name[j+1];
Avaliable[j]=Avaliable[j+1];
}
N=N-1;
showdata();
safe();
}
voidchangeresources(){修改资源函数
cout<<"系统目前可用的资源[Avaliable]:
"<for(inti=0;icout<"<cout<<"输入系统可用资源[Avaliable]:
"<cin>>Avaliable[0]>>Avaliable[1]>>Avaliable[2];
cout<<"经修改后的系统可用资源为"<for(intk=0;kcout<"<showdata();
safe();
}
voidaddprocess(){添加作业
intflag=M;
M=M+1;
cout<<"请输入该作业的最打需求量[Max]"<for(inti=0;icout<";
cin>>Max[flag][i];
Need[flag][i]=Max[flag][i]-Allocation[flag][i];
}
showdata();
safe();
}
intmain()主函数
{
inti,j,number,choice,m,n,flag;
charming;
cout<<"*****************资源管理系统的设计与实现*****************"<cout<<"请首先输入系统可供资源种类的数量:
";
cin>>n;
N=n;
for(i=0;icout<<"资源"<
";
cin>>ming;
name[i]=ming;
cout<<"资源的数量:
";
cin>>number;
Avaliable[i]=number;
}
cout<cout<<"请输入作业的数量:
";
cin>>m;
M=m;
cout<<"请输入各进程的最大需求量("<"<for(i=0;ifor(j=0;jcin>>Max[i][j];
do{
flag=0;
cout<<"请输入各进程已经申请的资源量("<"<for(i=0;ifor(j=0;jcin>>Allocation[i][j];
if(Allocation[i][j]>Max[i][j])
flag=1;
Need[i][j]=Max[i][j]-Allocation[i][j];
}
if(flag)
cout<<"申请的资源大于最大需求量,请重新输入!
\n";
}
while(flag);
showdata();显示各种资源
safe();用银行家算法判定系统是否安全
while(true){
cout<<"**************银行家算法演示***************"<cout<<"1:
增加资源"<cout<<"2:
删除资源"<cout<<"3:
修改资源"<cout<<"4:
分配资源"<cout<<"5:
增加作业"<cout<<"0:
离开"<cout<<"*******************************************"<cout<<"请选择功能号:
";
cin>>choice;
switch(choice){
case1:
addresources();break;
case2:
delresources();break;
case3:
changeresources();break;
case4:
share();break;
case5:
addprocess();break;
case0:
choice=0;break;
default:
cout<<"请正确选择功能号(0-5)!
"<}
}
return1;
}
【实验结果与分析】
【实验思考及总结】
银行家算法的安全算法不唯一,我们可以把操作系统看作是银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
操作系统按照银行家制定的规则为进程分配资源,当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过了该进程对资源的最大需求量。
若超过则拒绝分配资源,若没有超过则再测试系统现存的资源能否满足该进程尚需的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。
实验五页面置换算法模拟
【开发语言及实现平台或实验环境】
C++C#
MicrosoftVisualStudio6.0MicrosoftVisualStudio.NET2003
【实验目的】
(1)进一步理解利用页面调度算法实现虚拟内存的问题;
(2)通过模拟实现请求页式存储管理的几种基本页面置换算法,了解虚拟存储技术的特点。
(3)掌握虚拟存储请求页式存储管理中几种基本页面置换算法的基本思想和实现过程,并比较它们的效率。
(4)了解页面大小和内存实际容量对命中率的影响。
【实验内容】
(1)在了解和掌握页面调度算法的基础上,编制先进先出的算法(FIF