读者写者问题实验报告.docx

上传人:b****5 文档编号:27808723 上传时间:2023-07-05 格式:DOCX 页数:9 大小:18.59KB
下载 相关 举报
读者写者问题实验报告.docx_第1页
第1页 / 共9页
读者写者问题实验报告.docx_第2页
第2页 / 共9页
读者写者问题实验报告.docx_第3页
第3页 / 共9页
读者写者问题实验报告.docx_第4页
第4页 / 共9页
读者写者问题实验报告.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

读者写者问题实验报告.docx

《读者写者问题实验报告.docx》由会员分享,可在线阅读,更多相关《读者写者问题实验报告.docx(9页珍藏版)》请在冰豆网上搜索。

读者写者问题实验报告.docx

读者写者问题实验报告

读者写者问题实验报告

北京电子科技学院(BESTI)

实验报告课程:

操作系统班级:

姓名:

学号:

0921成绩:

指导教师:

实验日期:

2011.11.22徐小青

实验密级:

预习程度:

实验时间:

/12:

50-15:

20代码

仪器组次:

必修/选修:

实验序号:

A04必修

(一)实验名称:

用信号量来实现读者-写者问题

实验目的与要求:

理解进程(或线程)及信号量的概念

实验仪器:

名称型号数量

DELLPP33L微机1

一、实验目的:

理解进程(或线程)及信号量的概念

二、实验内容:

1、定义一个数据缓存buffer及用于实现同步互斥的信号量。

2、定义一个读者函数:

当有写者在占用buffer时,读者应该等待,直到写者不再使用该

buffer。

当有其他读者在占用buffer时,读者可对buffer进行读取操作。

当buffer中有数据时,则从其中读取一个数据,并显示然后退出。

当buffer中没有数据时,应等待,直到buffer中有数据可读。

3、定义一个写者函数

当有读者在占用buffer时,写者应该等待,直到所有的读者都退出

为止。

当有其他写者占用buffer时,该写者应该等待,直到占用buffer的写

者退出为止。

当buffer有空闲时,写者应该在buffer中写入一个数据并退出。

当buffer满时,写者应该等待,直到buffer有空闲为止。

、定义主函数,在其中可以任意创建读者与写者。

4

可根据用户输入创建读者或写者进程(线程)。

三、实验当堂完成内容:

1,将设计好的思路以代码形式呈现,并调通。

2,将数据改变,看结果是否符合预期设想

3,与同学交流,将代码完善。

四、设计思想:

读进程:

read()

{

P(Sr);申请区域

P(Scot);锁定读者计数器

first=first+1;

if(first==1)

P(Sdoc);

V(Scnt);解锁读者计数器

开始读;

P(Scnt);锁定读者计数器

V(Sdoc);

V(Scnt);

V(Sr);

}

写进程:

write()

{

P(sdoc);

开始写;

V(sdoc);

}

主函数设计思想:

开始

创建Sdoc、Sr、Scnt三个信

号量

inti=0

否i

创建读者线程

i++

iintj=0

否i

创建写者线程依次等待与执行j++i结束

i

五、代码及具体解释:

#include

#include

#include

#defineP(S)WaitForSingleObject(S,INFINITE)//这是Windows下多线程工作的P操作

#defineV(S)ReleaseSemaphore(S,1,NULL)//这是Windows下多线程工作的V操作

constintRN=5;//所有读者总数(可以改变)

constintWN=3;//所有写者总数(可以改变)

HANDLESdoc;//文档信号量——互斥量(临界区的信号量题目要求是1)HANDLESr;//读者信号量——广义信号量(一次最多有多少个读者在读)HANDLEScnt;//保护g_cntReader的互斥量(目前有多少读者正在读)intg_cntReader=0;//读者个数计数器

//funcname:

JustWait()//note:

显示一些信息,让后等待

//retval:

void

//

//+Parameter:

//[int]-nReader读者(写者)编号,读者>0,写者<0

//[int]-min操作等待的最短时间

//[int]-max操作等待得最长时间,实际等待的时间介于两者之间//[LPCSTR]-info要显示的信息

voidJustWait(intnReader,intmin,intmax,LPCSTRinfo);

DWORDWINAPIReader(LPVOIDlpPara);

DWORDWINAPIWriter(LPVOIDlpPara);//这是主函数

voidmain()

{

Sdoc=CreateSemaphore(NULL,1,1,"Document");//创建信号量初值,最大信号量值

Sr=CreateSemaphore(NULL,3,3,"ReaderNumber");//一次最多允许3个

读者读

Scnt=CreateSemaphore(NULL,1,1,"ReaderCounterProtect");//他也是一个互斥信号量,初值为1

HANDLEthreads[RN+WN];

for(inti=0;i

threads[i]=CreateThread(0,0,Reader,0,0,0);

for(intj=0;j

threads[j+RN]=CreateThread(0,0,Writer,0,0,0);

WaitForMultipleObjects(RN+WN,threads,TRUE,INFINITE);

}

//读者线程

DWORDWINAPIReader(LPVOIDlpPara)

{

//注意是静态变量,可以使每来一个读者增加一

staticintreader_num=1;

inti=reader_num++;

intx=0;

while(x<=5)

{

JustWait(i,1,2,"我想读");//1s的时候来,给2s的时间去读

P(Sr);//读者未满

P(Scnt);//锁定读者计数器

printf("还有%d个读者在读,读者%d进入\n",g_cntReader,i);

g_cntReader++;

if(g_cntReader==1)//如果是第一个读者

{

JustWait(i,1,2,"我是第一个!

");

P(Sdoc);//锁定文档

printf("读者%d说:

有人在读,不可写文件\n",i);

JustWait(i,1,2,"我可以读文件了~");

}

V(Scnt);//解锁读者计数器释放

JustWait(i,2,5,"我在读");//读ing…………

JustWait(i,1,2,"我将要离开~");

P(Scnt);//锁定读者计数器

g_cntReader--;

if(g_cntReader==0)//如果是最后一个

{

JustWait(i,1,2,"我是最后一个!

");

printf("读者%d说:

可以对文件操作了~~~~\n",i);

V(Sdoc);//解锁文档

}

printf("还有%d个读者在,读者%d离开\n",g_cntReader,i);

V(Scnt);//解锁读者计数器

V(Sr);//离开

JustWait(i,5,3,"结束");

x++;

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

}

return0;

}

DWORDWINAPIWriter(LPVOIDlpPara)

{

//注意是静态变量,可以使每来一个写者减去一,注意初值是负值

staticintg_cnt=-1;

intj=g_cnt--;

while

(1)

{

JustWait(j,2,4,"我想写");

//锁定文档

P(Sdoc);

printf("\t写者%d说:

文件正在修改不可操作\n",-j);

JustWait(j,4,3,"写?

?

?

");//写ing……

JustWait(j,1,2,"写完了,离开");

printf("写者%d说:

可以对文件操作了\n",-j);

V(Sdoc);//解锁文档

JustWait(j,8,4,"休息了");

}

return0;

}

voidJustWait(intnReader,intmin,intmax,LPCSTRinfo)//min为读者到来时间,max为读者离开时间

{

constintBASETIME=1000;//等待时间的基本量,以毫秒表示

intwait_time=0;//实际等待得时间

if(max==min)//判断是为了避免%0错误,注意取随机值

wait_time=min*BASETIME;//处理时间为0;

else

chars_out[128];//最终显示的信息缓冲

if(nReader>0)//读者大于0,写者小于0

sprintf(s_out,"读者%d说:

%s\n",nReader,info);

else

sprintf(s_out,"\t写者%d说:

%s\n",-nReader,info);

printf(s_out);//打印

Sleep(wait_time);//然后等待

}

//其设计思想是:

读者在读,来了写着,创建写着线程,利用时间片区分他们。

即定好某一个时间写者来,读一定时间以后离开。

六、实验编译过程遇到的问题:

1,未确定应该使用多线程还是单线程。

解决:

多线程是即使有读者在里边读,外边的写者依旧可以创建自己的线程,知道让出区域,便可以进去。

基于Windows里面具有API函数库,便确定使用多线程来处理。

2,在区域内的读者究竟多少个,

解决:

在读者写者问题中,区域内到底有多少个读者允许同时读。

故本次实验设信号量,Sr来计数本次实验中的临界区内的读者数量。

而且设定上限是3.

3,进程调度的机制是什么,

解决:

时间片轮流并设定。

每个读者或者写者定一个时间来,再定一定长度的时间离开。

比如JustWait(i,1,2,"我想读")是说1s的时候来,停留2s后出去。

七、实验运行中遇到的问题:

1、读者写者的个数不好计数,出现错误。

解决:

nReader的正数值表示读者数量,负值表示写着数量。

读者数量++,写着数量--,用一个变量计数并解决问题。

2、读者来的顺序不一定,是因为操作系统具有随机性。

解决:

等待时间具有随机性。

wait_time=rand()%(max*BASETIME-min*BASETIME)+min*BASETIME;

八、实验体会与心得:

此次实验是操作系统课程的第一次实验,编的是经典的读者写者问题。

首先要对读者写者问题有一个深刻的认识,才能落实到代码量上。

此次实验很多同学使用Linux下或者Unix的环境下编程,让我大开眼界。

我选择了比较大众化的C语言编程来实现此次实验。

在开始的时候对如何将读者写者问题转化到代码量非常疑惑,因为没有编写操作系统实验的思想,后来去图书馆查阅了一些书籍,看了一些伪代码,才有了一个初步的认识,最终确定用多线程编写。

大局方面,计算机的时钟是以毫秒来计算,因此BaseTime=1000,即以1s为一个时钟间隔。

在信号量的设计上,我采取了三个信号量,Sdoc(文档信号量,也是互斥量,此文档临界区的信号量,按照题目要求是1),Sr(读者信号量,一次临界区里最多有多少读者在里边读),Scnt(保护g_cntReader的互斥量)。

最后完善细节将代码调通。

这个过程很艰苦,而且有时候想不清楚的时候还要问其他同学,非常不容易。

但是这种学习使我收获很大。

学习不能闭门造车,也不能完全借鉴,要自己思考不清后交流。

期待下一次的操作系统实验,希望可有更多的收获

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

当前位置:首页 > 解决方案 > 商业计划

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

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