1、读者写者问题实验报告读者写者问题实验报告北京电子科技学院(BESTI) 实验报告 课程: 操作系统 班级: 姓名: 学号: 0921 成绩: 指导教师: 实验日期: 2011.11.22 徐小青 实验密级: 预习程度: 实验时间: / 12:50-15:20 代码 仪器组次: 必修/选修: 实验序号: A04 必修 (一) 实验名称: 用信号量来实现读者-写者问题 实验目的与要求: 理解进程(或线程)及信号量的概念 实验仪器: 名称 型号 数量 DELL PP33L 微机 1 一、实验目的: 理解进程(或线程)及信号量的概念 二、实验内容: 1、定义一个数据缓存buffer及用于实现同步互斥的
2、信号量。 2、定义一个读者函数: , 当有写者在占用buffer时,读者应该等待,直到写者不再使用该buffer。 , 当有其他读者在占用buffer时,读者可对buffer进行读取操作。 , 当buffer中有数据时,则从其中读取一个数据,并显示然后退出。 , 当buffer中没有数据时,应等待,直到buffer中有数据可读。 3、定义一个写者函数 , 当有读者在占用buffer时,写者应该等待,直到所有的读者都退出为止。 , 当有其他写者占用buffer时,该写者应该等待,直到占用buffer的写者退出为止。 , 当buffer有空闲时,写者应该在buffer中写入一个数据并退出。 , 当
3、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); 写进
4、程: write() P(sdoc); 开始写; V(sdoc); 主函数设计思想: 开始 创建Sdoc、Sr、Scnt三个信 号量 int i=0 否 iRN 是 创建读者线程 i+ i int j=0 否 iWN 是 创建写者线程 依次等待与执行 j+ i 结束 i 五、代码及具体解释: #include #include #include #define P(S) WaitForSingleObject(S, INFINITE)/ 这是 Windows 下多线程工作的 P 操作 #define V(S) ReleaseSemaphore(S, 1, NULL)/ 这是 Windows 下
5、多线程工作的 V 操作 const int RN = 5 ; / 所有读者总数(可以改变) const int WN = 3; / 所有写者总数(可以改变) HANDLE Sdoc; / 文档信号量互斥量(临界区的信号量 题目要求是1) HANDLE Sr; / 读者信号量广义信号量 (一次最多有多少个读者在读) HANDLE Scnt; / 保护 g_cntReader 的互斥量 (目前有多少读者正在读) int g_cntReader = 0; / 读者个数计数器 / funcname : JustWait ( ) / note: 显示一些信息,让后等待 / ret val : void
6、/ / + Parameter : / int - nReader 读者(写者)编号,读者0,写者0 / int - min 操作等待的最短时间 / int - max 操作等待得最长时间,实际等待的时间介于两者之间 / LPCSTR - info 要显示的信息 void JustWait(int nReader, int min, int max, LPCSTR info); DWORD WINAPI Reader(LPVOID lpPara); DWORD WINAPI Writer(LPVOID lpPara); / 这是主函数 void main() Sdoc = CreateSema
7、phore(NULL, 1, 1, Document);/ 创建信号量初值,最大信号量值 Sr = CreateSemaphore(NULL, 3, 3, ReaderNumber); / 一次最多允许 3 个读者读 Scnt = CreateSemaphore(NULL, 1, 1, ReaderCounterProtect);/ 他也是一个互斥信号量,初值为 1 HANDLE threadsRN+WN; for (int i=0; iRN; i+) /不断创建读者线程 threadsi = CreateThread(0, 0, Reader, 0, 0, 0); for (int j=0;
8、 jWN; j+) threadsj+RN = CreateThread(0, 0, Writer, 0, 0, 0); WaitForMultipleObjects(RN+WN, threads, TRUE, INFINITE); / 读者线程 DWORD WINAPI Reader(LPVOID lpPara) / 注意是静态变量,可以使每来一个读者增加一 static int reader_num = 1; int i = reader_num +; int x=0; while (x 0)/ 读者大于0,写者小于0 sprintf(s_out, 读者%d说: %sn, nReader,
9、 info); else sprintf(s_out, t写者%d说: %sn, -nReader, info); printf(s_out);/ 打印 Sleep(wait_time);/ 然后等待 /其设计思想是:读者在读,来了写着,创建写着线程,利用时间片区分他们。即定好某一个时间写者来,读一定时间以后离开。 六、实验编译过程遇到的问题: 1,未确定应该使用多线程还是单线程。 解决:多线程是即使有读者在里边读,外边的写者依旧可以创建自己的线程,知道让出区域,便可以进去。基于Windows里面具有API函数库,便确定使用多线程来处理。 2,在区域内的读者究竟多少个, 解决:在读者写者问题中
10、 ,区域内到底有多少个读者允许同时读。故本次实验设信号量,Sr来计数本次实验中的临界区内的读者数量。而且设定上限是3. 3,进程调度的机制是什么, 解决:时间片轮流并设定。每个读者或者写者定一个时间来,再定一定长度的时间离开。 比如JustWait(i, 1, 2, 我想读)是说1s的时候来,停留2s后出去。 七、实验运行中遇到的问题: 1、读者写者的个数不好计数,出现错误。 解决:nReader的正数值表示读者数量,负值表示写着数量。读者数量+,写着数量-,用一个变量计数并解决问题。 2、读者来的顺序不一定,是因为操作系统具有随机性。 解决:等待时间具有随机性。wait_time = ran
11、d()%(max*BASETIME-min*BASETIME) + min*BASETIME; 八、实验体会与心得: 此次实验是操作系统课程的第一次实验,编的是经典的读者写者问题。首先要对读者写者问题有一个深刻的认识,才能落实到代码量上。此次实验很多同学使用Linux下或者Unix的环境下编程,让我大开眼界。我选择了比较大众化的C语言编程来实现此次实验。 在开始的时候对如何将读者写者问题转化到代码量非常疑惑,因为没有编写操作系统实验的思想,后来去图书馆查阅了一些书籍,看了一些伪代码,才有了一个初步的认识,最终确定用多线程编写。 大局方面,计算机的时钟是以毫秒来计算,因此BaseTime=1000,即以1s为一个时钟间隔。在信号量的设计上,我采取了三个信号量,Sdoc(文档信号量,也是互斥量,此文档临界区的信号量,按照题目要求是1),Sr(读者信号量,一次临界区里最多有多少读者在里边读),Scnt(保护g_cntReader的互斥量)。 最后完善细节将代码调通。 这个过程很艰苦,而且有时候想不清楚的时候还要问其他同学,非常不容易。但是这种学习使我收获很大。学习不能闭门造车,也不能完全借鉴,要自己思考不清后交流。期待下一次的操作系统实验,希望可有更多的收获
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1