实验2线程同步机制.docx
《实验2线程同步机制.docx》由会员分享,可在线阅读,更多相关《实验2线程同步机制.docx(11页珍藏版)》请在冰豆网上搜索。
实验2线程同步机制
实验2线程同步机制
实验2线程同步机制
实验2线程同步机制
一、实验目的:
通过观察共享数据资源但不受控制的两个线程的并发运行输出结果,体会同步机制的必要性和重要性。
然后利用现有操作系统提供的同步机制编程实现关于该两个线程的有序控制,同时要求根据同步机制的Peterson软件解决方案尝试自己编程实现同步机制和用于同一问题的解决,并基于程序运行时间长短比较两种同步机制。
二、实验设计
I基于给定银行账户间转账操作模拟代码作为线程执行代码,在主线程中创建两个并发线程,编程实现并观察程序运行结果和予以解释说明。
II利用Windows互斥信号量操作函数解决上述线程并发问题,并分析、尝试和讨论线程执行体中有关信号量操作函数调用的正确位置。
III根据同步机制的Peterson软件解决方案尝试自己编程实现线程同步机制和用于上述线程并发问题的解决,并基于程序运行时间长短
实验2线程同步机制
将其与基于Windows互斥信号量的线程同步机制的效率展开比较。
其间,可规定线程主体代码循环执行1000000次
三、源程序清单和说明
1未利用互斥信号量
#include
#include
#include
intnAccount1=0,nAccount2=0;intnLoop=0;
intnTemp1,nTemp2,nRandom;
DWORDWINAPIThreadFunc(HANDLEThread){
do
{
nTemp1=nAccount1;
nTemp2=nAccount2;
nRandom=rand();
nAccount1=nTemp1+nRandom;
nAccount2=nTemp2-nRandom;
nLoop++;
}while((nAccount1+nAccount2)==0);printf("循环次数为%d\n",nLoop);
return0;
}
intmain()
{
HANDLEThread[2];
Thread[0]=CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);
Thread[1]=CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);
WaitForMultipleObjects(2,Thread,TRUE,INFINITE);
CloseHandle(Thread);
return0;
}
实验2线程同步机制
2利用Windows互斥信号量
#include
#include
#include
#defineCOUNT1000000
intnAccount1=0,nAccount2=0;HANDLEmutex;
DWORDWINAPIThreadFunc(HANDLEThread){
intnLoop=0;
intnTemp1,nTemp2,nRandom;
WaitForSingleObject(mutex,INFINITE);do
{
nTemp1=nAccount1;
nTemp2=nAccount2;
nRandom=rand();
nAccount1=nTemp1+nRandom;
nAccount2=nTemp2-nRandom;
nLoop++;
ReleaseMutex(mutex);
WaitForSingleObject(mutex,INFINITE);
}
while((nAccount1+nAccount2)==0&&nLoopReleaseMutex(mutex);
WaitForSingleObject(mutex,INFINITE);printf("循环次数为%d\n",nLoop);
ReleaseMutex(mutex);
return0;
}
intmain()
{
HANDLEThread[2];
DWORDstart,end;
start=GetTickCount();
mutex=CreateMutex(NULL,FALSE,NULL);
Thread[0]=CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);
Thread[1]=CreateThread(NULL,0,ThreadFunc,NULL,0,NULL);
实验2线程同步机制
WaitForMultipleObjects(2,Thread,TRUE,INFINITE);
end=GetTickCount();
printf("总共用时%ld\n",end-start);
CloseHandle(Thread);
CloseHandle(mutex);
return0;
}
3同步机制的Peterson
#include
#include
#include
#defineCOUNT1000000
intnAccount1=0,nAccount2=0,flag[2],turn;
intnLoop=0;
intnTemp1,nTemp2,nRandom;//HANDLEmutex;
voidrequest(intid)
{
intother=1-id;
flag[id]=1;
turn=other;
while(flag[other]==1&&turn==other){};
}
DWORDWINAPIThreadFunc0(HANDLEThread)
{
request(0);
do
{
nTemp1=nAccount1;
nTemp2=nAccount2;
nRandom=rand();
nAccount1=nTemp1+nRandom;
nAccount2=nTemp2-nRandom;
nLoop++;
flag[0]=0;
request(0);
}
while((nAccount1+nAccount2)==0&&nLoopflag[0]=0;
实验2线程同步机制
request(0);
flag[0]=0;
printf("循环次数为%d\n",nLoop);
return0;
}
DWORDWINAPIThreadFunc1(HANDLEThread)
{
request
(1);
do
{
nTemp1=nAccount1;
nTemp2=nAccount2;
nRandom=rand();
nAccount1=nTemp1+nRandom;
nAccount2=nTemp2-nRandom;
nLoop++;
flag[1]=0;
request
(1);
}
while((nAccount1+nAccount2)==0&&nLoopflag[1]=0;
request
(1);
flag[1]=0;
printf("循环次数为%d\n",nLoop);
return0;
}
intmain()
{
HANDLEThread[2];
DWORDstart,end;
start=GetTickCount();
Thread[0]=CreateThread(NULL,0,ThreadFunc0,NULL,0,NULL);
Thread[1]=CreateThread(NULL,0,ThreadFunc1,NULL,0,NULL);
WaitForMultipleObjects(2,Thread,TRUE,INFINITE);
end=GetTickCount();
printf("总共用时%ld\n",end-start);
CloseHandle(Thread);
return0;
}
实验2线程同步机制
四、算法及关键数据结构设计
1.银行账户间转账操作模拟
intnAccount1=0,nAccount2=0;//主线程创建的全局变量
intnLoop=0;
intnTemp1,nTemp2,nRandom;
do
{
nTemp1=nAccount1;
nTemp2=nAccount2;
nRandom=rand();
nAccount1=nTemp1+nRandom;
nAccount2=nTemp2-nRandom;
nLoop++;
}while((nAccount1+nAccount2)==0);
printf("循环次数为%d\n",nLoop);
2.进程互斥算法1,设置访问编号Varturn:
integer:
=i;
repeat
……
whileturn,idono_op;
临界区
turn:
=j;
……
untilfalse;
3.进程互斥算法2,设置访问标志Varflag,flag:
boolean:
=false,false;ij
repeat
whileflagdono_op;j
flag:
=true;i
临界区
flag:
=false;i
untilfalse;
4.进程互斥算法3,设置访问标志Varflag,flag:
boolean:
=false,false;ij
repeat
flag:
=true;i
实验2线程同步机制
whileflagdono_op;j
临界区
flag:
=false;i
untilfalse;
5.进程互斥算法4,编号+标志
Varflag,flag:
boolean;ij
turn:
integer;
repeat
flag:
=true;turn:
=j;i
while(flagandturn=j)dono_op;j
临界区
flag:
=false;i
untilfalse;
五、实验过程中间结果屏幕截图
实验结果1未利用互斥信号量
2利用Windows互斥信号量
实验2线程同步机制
3同步机制的Peterson
实验2线程同步机制
结果分析
1没有应用互斥信号量对线程进行并发控制,运行会产生错误。
2利用Windows互斥信号量后,两存取款线程可并发正确执行。
成功转账100000次。
但加大了系统的时间开销。
时间效率低。
3应用同步机制的Peterson算法后,两线程也可顺利的并发执行,成功转账100000次,但相对于Windows互斥信号量,时间明显缩短。
改善了系统的运行时间,提高了时间效率。
六、疑难解惑及经验教训
通过本次试验实现了两个线程的并发运行。
对于共享数据资源但不受控制的两个线程的并发运行,会出现错误结果。
因此同步机制是必要的。
实验中利用Windows互斥信号量和同步机制的Peterson算法实现了关于该两个线程的有序控制,实现了同步机制和用于同一问题的解决。
并了解了两种方案的效率。
同步机制的Peterson算法要明显优于Windows互斥信号量。