北交大操作系统作业进程同步实验.docx

上传人:b****7 文档编号:9738253 上传时间:2023-02-06 格式:DOCX 页数:12 大小:187.68KB
下载 相关 举报
北交大操作系统作业进程同步实验.docx_第1页
第1页 / 共12页
北交大操作系统作业进程同步实验.docx_第2页
第2页 / 共12页
北交大操作系统作业进程同步实验.docx_第3页
第3页 / 共12页
北交大操作系统作业进程同步实验.docx_第4页
第4页 / 共12页
北交大操作系统作业进程同步实验.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

北交大操作系统作业进程同步实验.docx

《北交大操作系统作业进程同步实验.docx》由会员分享,可在线阅读,更多相关《北交大操作系统作业进程同步实验.docx(12页珍藏版)》请在冰豆网上搜索。

北交大操作系统作业进程同步实验.docx

北交大操作系统作业进程同步实验

进程同步实验2

实验目的2

实验过程2

1.制造混乱2

实验结果:

4

结果分析:

4

2.mutex方案5

实验结果:

6

结果分析:

7

3.软件方案7

实验结果:

10

结果分析:

11

进程同步实验

实验目的

讨论临界区问题及其解决方案。

实验首先创建两个共享数据资源的并发线程。

在没有同步控制机制的情况下,我们将看到某些异常现象。

针对观察到的现象,本实验采用两套解决方案:

•利用Windows的mutex机制

•采用软件方案

然后比较这两种方案的性能优劣。

实验过程

1.制造混乱

Windows操作系统支持抢先式调度,这意味着一线程运行一段时间后,操作系统会暂停其运行并启动另一线程。

也就是说,进程内的所有线程会以不可预知的步调并发执行。

为了制造混乱,我们首先创建两个线程t1和t2。

父线程(主线程)定义两个全局变量,比如accnt1和accnt2。

每个变量表示一个银行账户,其值表示该账户的存款余额,初始值为0。

线程模拟在两个账户之间进行转账的交易。

也即,每个线程首先读取两个账户的余额,然后产生一个随机数r,在其中一个账户上减去该数,在另一个账户上加上该数。

线程操作的代码如下:

#include

#include

#include

intaccnt1=0;

intaccnt2=0;

doublebegin=0,end=0,time=0;

inti=1;

DWORDWINAPIrun(LPVOIDp){

intcounter=0;

inttmp1,tmp2,r;

begin=GetTickCount();

do{

tmp1=accnt1;

tmp2=accnt2;

r=rand();

accnt1=tmp1+r;

accnt2=tmp2-r;

counter++;

}while(accnt1+accnt2==0&&counter<);

end=GetTickCount();

time=end-begin;

printf("counter=%d\n",counter);

printf("进程%d用时%lf\n",i,time);

i++;

counter=0;

return0;

}

intmain(intargc,char*argv[])

{

CreateThread(NULL,0,run,NULL,0,NULL);

CreateThread(NULL,0,run,NULL,0,NULL);

system("PAUSE");

return0;

}

实验结果:

结果分析:

两个线程执行相同的代码。

由于执行过程相互交叉,某线程就有可能访问到新的accnt1值和老的accnt2值,从而导致账户余额数据发生混乱。

线程一旦检测到混乱的发生,便终止循环并打印交易的次数(counter)。

从实验结果可看出,每次进程二可全部完成,但是用时不一定,而进程一不一定能全部完成。

2.mutex方案

利用mutex对象,可以方便地实现临界区保护。

进入临界区时(在第一个读操作之前),锁住mutex对象;离开临界区时(在第二个写操作之后),打开mutex对象。

线程的阻塞与唤醒由系统管理,程序员无需干预。

以下给出的是在Windows操作系统下有关mutex对象操作的代码。

#include

#include

#include

intaccnt1=0;

intaccnt2=0;

doublebegin=0,end=0,time=0;

HANDLEhMutex;

inti=1;

DWORDWINAPIrun(LPVOIDp)

{

intcounter=0;

inttmp1,tmp2,r;

WaitForSingleObject(hMutex,INFINITE);

begin=GetTickCount();

do

{

tmp1=accnt1;

tmp2=accnt2;

r=rand();

accnt1=tmp1+r;

accnt2=tmp2-r;

counter++;

}

while(accnt1+accnt2==0&&counter<);

end=GetTickCount();

time=end-begin;

printf("进程%d用时%lf\n",i,time);

printf("%d\n",counter);

i++;

ReleaseMutex(hMutex);

counter=0;

}

intmain(intargc,char*argv[])

{

hMutex=CreateMutex(NULL,FALSE,NULL);

CreateThread(NULL,0,run,NULL,0,NULL);

CreateThread(NULL,0,run,NULL,0,NULL);

system("PAUSE");

return0;

}

实验结果:

 

结果分析:

进程一平均用时:

28.4毫秒,进程二平均用时:

28毫秒,进程一和进程二都完成的平均用时是56.4毫秒。

从运行结果可以看出,利用mutex方案可以较为有效地解决临界资源访问问题。

进程一和进程二在次测试中都能够准确完成。

且进程一和进程二用时较为接近。

3.软件方案

假设操作系统没有提供同步原语。

这时,我们只能通过编程语言对变量的操作实现临界区保护。

设计方案如下:

#include

#include

#include

intaccnt1=0,accnt2=0;

DWORDWINAPIrun_1(LPVOIDp)

{

intcounter=0;

inttmp1=0,tmp2=0,r;

doublebegin=0,end=0,time=0;

begin=GetTickCount();

do

{

tmp1=accnt1;

tmp2=accnt2;

r=rand();

accnt1=tmp1+r;

accnt2=tmp2-r;

counter++;

}

while(accnt1+accnt2==0&&counter<);

printf("进程一counter=%d\n",counter);

end=GetTickCount();

time=end-begin;

printf("进程一用时:

%lf\n",time);

counter=0;

return0;

}

DWORDWINAPIrun_2(LPVOIDp)

{

intcounter=0;

inttmp1=0,tmp2=0,r;

doublebegin=0,end=0,time=0;

begin=GetTickCount();

do

{

tmp1=accnt1;

tmp2=accnt2;

r=rand();

accnt1=tmp1+r;

accnt2=tmp2-r;

counter++;

}

while(accnt1+accnt2==0&&counter<);

printf("进程二counter=%d\n",counter);

end=GetTickCount();

time=end-begin;

printf("进程二用时:

%lf\n",time);

counter=0;

return0;

}

intmain(intargc,char*argv[])

{

intc1=0,c2=0;

intwill_wait;

while

(1)

{

c1=1;

will_wait=1;

while(c2&&(will_wait==1));

CreateThread(NULL,0,run_1,NULL,0,NULL);

//break;

c1=0;

break;

}

while

(1)

{

c2=1;

will_wait=2;

while(c1&&(will_wait==2));

CreateThread(NULL,0,run_2,NULL,0,NULL);

//break;

c2=0;

break;

}

system("PAUSE");

return0;

}

实验结果:

结果分析:

从进程一和进程二中选取都完成了次计算的进程,选取五次计算平均结果。

进程一平均用时:

31毫秒,进程二平均用时:

25.2毫秒,进程一和进程二完成的平均用时是56.2毫秒.mutex方案与软件方案相比,用时较为接近,进程一和进程二的执行前后顺序不一定。

但是在软件方案中,进程一和进程二在测试中不一定能够执行完次,此方案不能对进程有效加解锁。

疑问:

从代码分析,c1和c2解决了资源的互斥访问,will_wait解决了“饥饿”现象,但是为什么执行结果和分析的不一样?

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

当前位置:首页 > 幼儿教育 > 育儿理论经验

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1