操作系统读者与写者问题课程设计报告
操作系统课程设计报告——读者写者问题
操作系统课程设计课题:读者写者问题姓名:赫前进班级:1020552学号102055211指导教师:叶瑶提交时间:2012/12/30(一)实验目的1.进一步理解“临界资源”的概念;2.把握在多个进程并发执行过程中对临界资源访问时的必要约束条件;3.理解操作系统原理中“互斥”和“同步”的涵义。
(二)实验内容利用程序设计语言编程,模拟并发执行进程的同步与互斥(要求:进程数目不少于3 个)。
(三)、程序分析读者写者问题的定义如下:有一个许多进程共享的数据区,这个数据区可以是一个文件或者主存的一块空间;有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进程(Writer),此外还需要满足以下条件:(1)任意多个读进程可以同时读这个文件;(2)一次只有一个写进程可以往文件中写;(3)如果一个写进程正在进行操作,禁止任何读进程度文件。
实验要求用信号量来实现读者写者问题的调度算法。
实验提供了signal类,该类通过P( )、V( )两个方法实现了P、V原语的功能。
实验的任务是修改Creat_Writer()添加写者进程,Creat_Reader()创建读者进程。
Reader_goon()读者进程运行函数。
读优先:要求指一个读者试图进行读操作时,如果这时正有其他读者在进行操作,他可直接开始读操作,而不需要等待。
读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。
写优先:一个读者试图进行读操作时,如果有其他写者在等待进行写操作或正在进行写操作,他要等待该写者完成写操作后才开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
在Windows 7 环境下,创建一个控制台进程,此进程包含n 个线程。
用这n 个线程来表示n 个读者或写者。
每个线程按相应测试数据文件(格式见下)的要求进行读写操作。
读者写者实验报告
读者写者实验报告
读者写者问题是指一个共享固定大小缓冲区的进程间通信问题,其中固定大小的缓冲区被多个读者进程和写者进程所共享。
读者进程从缓冲区中读取数据,而写者进程将数据写入缓冲区。
本实验目的是通过使用互斥锁、条件变量和信号量等同步机制,构建一个读者写者问题的解决方案。
实验环境:
- 操作系统:Linux
-编程语言:C语言
实验步骤:
1.创建共享内存缓冲区,用于读者和写者的数据传递。
2.创建互斥锁,用于保护共享内存缓冲区的访问。
3.创建条件变量,用于读者和写者之间的协调。
4.创建读者进程和写者进程,模拟读者写者的并发操作。
5.在读者进程中,通过互斥锁保护共享内存缓冲区,读取数据,并更新计数器。
6.在写者进程中,通过互斥锁保护共享内存缓冲区,写入数据,并更新计数器。
7.使用条件变量实现读者优先或写者优先的策略。
实验结果:
通过实验,我成功实现了读者写者问题的解决方案。
使用互斥锁可以保护共享资源的访问,防止读者和写者同时访问。
使用条件变量可以实现读者优先或写者优先的策略。
实验总结:
通过本次实验,我深入了解了读者写者问题,并且掌握了使用互斥锁、条件变量和信号量等同步机制来解决读者写者问题的方法。
在实现过程中,我遇到了一些困难,例如死锁和竞争条件等问题。
通
过调试和改进代码,我成功解决了这些问题,提高了程序的稳定性和性能。
在以后的工作中,我会更加注重并发编程的实践,提高自己解决问题
的能力。
操作系统课程设计--读者-写者问题
操作系统课程设计报告一、操作系统课程设计任务书读者-写者问题实现1设计目的通过实现经典的读者写者问题,巩固对线程及其同步机制的学习效果,加深对相关基本概念的理解,并学习如何将基本原理和实际设计有机的结合。
2设计要求在Windows 2000/XP环境下,使用多线程和信号量机制实现经典的读者写者问题,每个线程代表一个读者或一个写者。
每个线程按相应测试数据文件的要求,进行读写操作。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制:(1)写-写互斥,即不能有两个写者同时进行写操作(2)读-写互斥,即不能同时有一个读者在读,同时却有一个写者在写(3)读-读允许,即可以有二个以上的读者同时读读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确信所有处理都遵守相应的读写操作限制。
3测试数据文件格式测试数据文件包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。
每行测试数据包括四个字段,各字段间用空格分隔。
第一字段为一个正整数,表示线程序号。
第二字段表示相应线程角色,R表示读者是,W表示写者。
第三字段为一个正数,表示读写操作的开始时间。
线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。
第四字段为一个正数,表示读写操作的持续时间。
当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。
下面是一个测试数据文件的例子:1 r 3 52 w 4 53 r 5 24 r 6 55 w 5.1 34相关API函数CreateThread()在调用进程的地址空间上创建一个线程ExitThread()用于结束当前线程Sleep()可在指定的时间内挂起当前线程CreateMutex()创建一个互斥对象,返回对象句柄OpenMutex()打开并返回一个已存在的互斥对象句柄,用于后续访问ReleaseMutex()释放对互斥对象的占用,使之成为可用WaitForSingleObject()可在指定的时间内等待指定对象为可用状态InitializeCriticalSection()初始化临界区对象EnterCriticalSection()等待指定临界区对象的所有权LeaveCriticalSection()释放指定临界区对象的所有权文件系统的设计通过对文件系统的设计,加深理解文件系统的内部功能及内部实现。
读者写者问题-操作系统实验报告 (1)
实验内容1、定义一个数据缓存buffer 及用于实现同步互斥的信号量。
2、定义一个读者函数:● 当有写者在占用buffer 时,读者应该等待,直到写者不再使用该buffer 。
● 当有其他读者在占用buffer 时,读者可对buffer 进行读取操作。
● 当buffer 中有数据时,则从其中读取一个数据,并显示然后退出。
● 当buffer 中没有数据时,应等待,直到buffer 中有数据可读。
3、定义一个写者函数● 当有读者在占用buffer 时,写者应该等待,直到所有的读者都退出为止。
● 当有其他写者占用buffer 时,该写者应该等待,直到占用buffer 的写者退出为止。
● 当buffer 有空闲时,写者应该在buffer 中写入一个数据并退出。
● 当buffer 满时,写者应该等待,直到buffer 有空闲为止。
4、定义主函数,在其中可以任意创建读者与写者。
● 可根据用户输入创建读者或写者进程(线程)。
5、用户界面2. 写者: 开始 读出的内容: 1. 读者:开始 结束 2 1 读者队列等待结束写出的内容: Hello world !结束实验当堂所要完成事情列表:1.调试程序使其在读者优先模式下可以运行并且能实现基本的功能得出正确的结果:能够实现读写互斥,写写互斥,读读不互斥,一个进程结束能够唤醒等待队列中的进程(先读者队列后写着队列)2.根据实验要求完善功能:由用户决定写者向缓冲区中写入的内容,读者能够读出并显示出来;当缓冲区中没有数据时,读者要等待,直到缓冲区中有数据才能读3.根据“读者优先”加以改变,增加一个“写者优先”模式,并且由用户来选择模式源代码:#include<stdio.h>#include<stdlib.h>int rcount=0;//正在读的读者数量int wcount=0;//写者队列中等待写操作的写者数量int read_id=0;//读进程号int write_id=0;//写进程号int w=1;//读写互斥信号量char temp[300] = {'\0'};int choice; //用户选择读者优先OR写者优先int sign; //标识temp空的信号量 0表示temp空void WFwakeup();void RFwakeup();struct rqueue{//读者等待队列int readers[200];int index;}rq;struct wqueue{//写者等待队列int writers[200];int index;}wq;/*void first(){ //初始化int i;rq.index = 0;wq.index = 0;for(i = 0;i<20;i++){rq.readers[i] = 0;wq.writers[i] = 0;}}*///*******************************************读进程读操作void read(){int i = 0;read_id++;if(rcount == 0){//当前没有读进程在读可能有写进程在写可能CPU空闲if(w==1) {//如果CPU空闲,读者拿到CPUw--;// 相当于一个P操作rcount++;if(temp[0] == '\0'){sign = 0;if(choice == 1){rq.readers[rq.index++]=read_id;//将读者进程加入等待队列RFwakeup();return;}else{rq.readers[rq.index++]=read_id;//将读者进程加入等待队列WFwakeup();return;}}//ifprintf("读者%d正在读\n",read_id);for(i = 0;i < 300;i++){//读取temp内容即写者写的内容if(temp[i] == '\0'){printf("\n");return;}//ifprintf("%c",temp[i]);}//for}//ifelse{//写者线程正在执行printf("!有写者在写不能读!\n");rq.readers[rq.index++]=read_id;//将读者进程加入等待队列}//else}//ifelse{//rcount !=1 则知道当前已经有读者在读,读读不互斥,则这个读者可以直接进来了读printf("读者%d正在读\n",read_id);for(i = 0;i < 300;i++){if(temp[i] == '\0'){printf("\n");return;}printf("%c",temp[i]);}//for}//else}//***************************写进程写操作void write(){write_id++;if(w == 0){if(rcount != 0 ){//有读者进程在执行printf("!有读者在读不能写!\n");wq.writers[wq.index++]=write_id;//将写者进程加入等待队列wcount++;return;}if(rcount == 0 ){//rcount == 0则当前无读者,但w = 0,所以有写者在写printf("!有写者在写不能写!\n");wq.writers[wq.index++]=write_id;//将写者进程加入等待队列wcount++;return;}}if(w == 1){w--;printf("写者%d正在写\n请输入要写的内容",write_id);scanf("%s",temp);//while}//if}//************************读者优先时唤醒进程void RFwakeup(){int i = 0;int j = 0;int m,n;m = rq.index;// n = wq.index;if(rcount == 0){//当前无读进程,是写者在写 --》停止运行写进程bool reader_wait=false;w=1;printf("写者已经写完\n");sign = 1;//temp中已经有内容要置1for(i=0;i<=m;i++){// i ndex为当前读者队列中的等待进程数if(rq.readers[i]!=0){reader_wait=true; //确实有读者在等待printf("等待的读者%d正在读\n",rq.readers[i]);w = 0;for(j = 0;j < 300;j++){if(temp[j] == '\0'){printf("\n");break;}//ifprintf("%c",temp[j]);}//forrq.readers[i]=0;rcount++;rq.index--;}//if}//forif(!reader_wait){//没有读者等待,看是否有写者等待for(int i=0;i<=wq.index;i++){//检查写者等待队列if(wq.writers[i]!=0){w = 0;printf("等待的写者%d正在写\n请输入要写入的内容",wq.writers[i]);scanf("%s",temp);wq.writers[i]=0;wcount--;break;}//if}//for}//if// return;}//ifelse{//rcount != 0读者正在读,stop读此时若有等待必为写者rcount=0;w = 1;if(sign == 0){printf("缓冲区空等待写者\n");return;}else{printf("读者已经读完\n");for(int i=0;i<=wq.index;i++){// 检查写者等待队列if(wq.writers[i]!=0){w = 0;printf("等待的写者%d正在写\n请输入要写入的内容",wq.writers[i]);scanf("%s",temp);wq.writers[i]=0;wcount--;break;}//if}//for}}//else}//******************************************写者优先唤醒void WFwakeup(){int i = 0;int j = 0;int m,n;m = rq.index;//n = wq.index;if(rcount == 0){//当前无读进程,是写者在写 --》停止运行写进程bool writer_wait=false;w=1;printf("写者已经写完\n");sign = 1;//temp中已经有内容要置1for(i=0;i<=wq.index;i++){// index为当前写者队列中的等待进程数if(wq.writers[i]!=0){writer_wait=true; //确实有写者在等待printf("等待的写者%d正在写\n 请输入要写的内容\n",wq.writers[i]);w = 0;scanf("%s",temp);wq.writers[i]=0;wcount--;break;}}if(!writer_wait){//没有xie者等待,看是否有du者等待for(int i=0;i<=m;i++){//检查写者等待队列if(rq.readers[i]!=0){w = 0;printf("等待的读者%d正在读\n",rq.readers[i]);for(j = 0;j < 300;j++){if(temp[j] == '\0'){printf("\n");rq.index--;break;}//ifprintf("%c",temp[j]);}//forrq.readers[i]=0;rcount++;}//if}//for}//if// return;}//ifelse{//rcount != 0读者正在读,stop读此时若有等待必为写者rcount=0;w = 1;printf("读者已经读完\n");for(int i=0;i<=wq.index;i++){// 检查写者等待队列if(wq.writers[i]!=0){w = 0;printf("等待的写者%d正在写\n请输入要写入的内容",wq.writers[i]);scanf("%s",temp);wq.writers[i]=0;wcount--;break;}//if}//for}}void menu1(){char i;printf(" 1-创建读者进程\n 2-创建写者进程\n 3-结束当前执行的进程\n 4-退出程序\n");printf("*******************************************\n");do{printf("当前队列中有读者: %d个写者: %d个\n",rq.index,wcount);printf("*******************************************\n");printf(" ----->");scanf("%s",&i);switch(i){case '1':read();break;case '2':write();break;case '3':RFwakeup();break;case '4':exit(0);default:printf("输入错误请重新输入\n");}}while(true);}void menu2(){char i;printf(" 1-创建读者进程\n 2-创建写者进程\n 3-结束当前执行的进程\n 4-退出程序\n");printf("*******************************************\n");do{printf("当前队列中有读者: %d个写者: %d个\n",rq.index,wcount);printf("*******************************************\n");printf(" ----->");scanf("%s",&i);switch(i){case '1':read();break;case '2':write();break;case '3':WFwakeup();break;case '4':exit(0);default:printf("输入错误请重新输入\n");}}while(true);}void main(){printf("*************************************************** ***********************\n");printf(" 20092104实验一\n 1.读者优先\n 2.写者优先\n");scanf("%d",&choice);while(1){if(choice == 1)menu1();if(choice == 2)menu2();if(choice != 1 && choice != 2){printf("输入错误请重新输入\n");scanf("%d",&choice);}}}实验流程图:N Y开始 读者优先 写者优先 读操作 写操作 是否有读者在读进行读操作 YCPU 是否空闲 缓冲区是否为空有写者 读者入队 N Y 入读者等待队列 调用读者优先唤醒 读操作 N 是否有读者在读 有读者 写者入队 Y N Cpu 是否空闲进行写操作 有写者,写操作入队 YN 退出 结束 读者优先唤醒 写者优先唤醒核心部分设计思路:读者优先唤醒当前有无读者在读有无读者等待N有无写者等待N 读者出队进行读操作直到读者队空Y进行写操作 YN 返回Y缓冲区是否为空YN写者优先唤醒当前有无读者在读有无写者等待N有无读者等待N 写者出队进行写操作直到写者队空Y进行读操作直到读者队列为空YN 返回YN写者队列是否为空进行写操作直到写者队列为空Y有读者说明若有等待必为写者分别用两个队列来存放等待的读者进程和写者进程,一个进程结束后就要将因他阻塞的进程唤醒,如果是读者优先,则先检查读者进程,如果发现读者进程不为空,就进行读操作,直到读者进程为空,才进行写操作;同理,如果是写者优先,则先检查写进程,如果发现写者进程不为空,就进行写操作,直到写者进程为空,才进行读操作。
OS课程设计__读者写者
兰州交通大学操作系统课程设计课程:计算机操作系统题目:进程同步(读者--写者)班级:姓名:学号:指导教师:日期:2012年12月21日目录1题目 (1)2设计概述 (1)2.1问题描述 (1)2.2采用信号量机制 (1)3课程设计目的及功能 (1)3.1设计目的 (1)3.2设计功能 (1)4总体设计思想概述 (2)4.1功能流程图 (2)4.2开发平台及源程序的主要部分 (3)4.3数据结构 (3)4.4模块说明 (3)4.5源程序 (3)5测试用例,运行结果与运行情况分析 (12)5.1测试用例 (12)5.2运行结果 (12)5.3运行结果分析 (14)6总结与心得 (15)1题目进程同步模拟设计——读者和写者问题2设计概述2.1问题描述模拟用信号量机制实现读者和写者问题,即有两组并发进程:读者和写者,共享一组数据区,进行读写操作,要求任一时刻“写者”最多只允许一个,而“读者”则允许多个。
2.1.1要求允许多个读者同时执行读操作;不允许读者、写者同时操作;不允许多个写者同时操作。
2.1.2读者和写者的相互关系:2.2采用信号量机制1)Wmutex表示读写的互斥信号量,初值: Wmutex =1;2)公共变量Rcount表示“正在读”的进程数,初值:Rcount =0;3)Rmutex:表示对Rcount的互斥操作,初值:Rmutex=1。
3课程设计目的及功能3.1设计目的通过实验模拟读者和写者之间的关系,了解并掌握他们之间的关系及其原理。
由此增加对进程同步的问题的了解。
具体如下:1)掌握基本的同步互斥算法,理解读者和写者模型;2)了解windows中多线程(多进程)的并发执行机制,线程(进程)间的同步和互斥;3)学习使用windows中基本的同步对象,掌握相应的API。
3.2设计功能利用模拟用信号量机制实现读者和写者问题:通过用户控制读进程和写进程,反应读者和写者问题中所涉及的进程的同步与互斥。
(完整word版)操作系统课程设计-读者写者问题
操作系统课程设计报告一、开题报告(一)该项课程设计的意义;1.更加深入的了解读者写者问题的算法;2.加深对线程,进程的理解;3.加深对“线程同步”概念的理解,理解并应用“信号量机制”;4.熟悉计算机对处理机的管理,了解临界资源的访问方式;5.了解C++中线程的实现方式,研读API。
(二)课程设计的任务多进程/线程编程:读者-写者问题。
●设置两类进程/线程,一类为读者,一类为写者;●随机启动读者或写者;●显示读者或写者执行状态;●随着进程/线程的执行,更新显示;(三)相关原理及算法描述;整体概况:该程序从大体上来分只有两个模块,即“读者优先”和“写者优先”模块.读者优先:如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount记录读者数目,用于确定是否释放读者线程,readcount的初值为0.当线程开始调入时.每个读者准备读. 等待互斥信号,保证对readcount 的访问,修改互斥.即readcount++.而当读者线程进行读操作时,则读者数目减少(readcount--).当readcout=0 时,说明所有的读者都已经读完,离开临界区唤醒写者(LeaveCriticalSection(&RP_Write);), 释放互斥信号(ReleaseMutex(h_Mutex)).还需要一个互斥对象mutex来实现对全局变量Read_count修改时的互斥. 另外,为了实现写-写互斥,需要增加一个临界区对象Write。
当写者发出写请求时,必须申请临界区对象的所有权。
通过这种方法,可以实现读-写互斥,当Read_count=1时(即第一个读者到来时),读者线程也必须申请临界区对象的所有权写者优先:写者优先与读者不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。
为此应当填加一个整形变量write_count,用于记录正在等待的写者的数目,write_count的初值为0.当线程开始调入时.只允许一个写者准备读. 等待互斥信号,保证对write_count的访问,修改互斥.即write_count++.而当写者线程进行读操作时,则相应写者数目减少(write_count--).当write_count=0 时,说明所有的读者都已经读完,离开临界区唤醒读者,释放互斥信号.为了实现写者优先,应当填加一个临界区对象read,当有写者在写文件或等待时,读者必须阻塞在read上。
读者写者问题实验报告
读者写者问题实验报告1. 引言读者写者问题是操作系统中的经典同步问题,用于研究多线程环境下对共享资源的访问和保护。
在该问题中,有多个读者和写者同时对一个共享资源进行操作,需要保证并发访问时的正确性和效率。
通过本实验,我们将探讨读者写者问题的解决方案,并比较不同算法的性能差异。
2. 实验目标本实验的主要目标是通过实现和比较不同的读者写者问题算法,深入了解并发访问的挑战和解决方案。
具体而言,我们将研究以下几个方面:•设计并实现读者写者问题的解决方案•比较不同算法的性能差异•分析可能的优化策略3. 实验方法我们将使用Python编程语言来实现读者写者问题的解决方案。
在实验过程中,我们将尝试以下几种常见的算法:3.1. 读者优先算法在读者优先算法中,当有读者在访问共享资源时,其他读者可以同时访问,但写者需要等待。
只有当所有读者完成访问后,写者才能获得访问权限。
3.2. 写者优先算法在写者优先算法中,当有写者在访问共享资源时,其他读者和写者都需要等待。
只有当写者完成访问后,其他读者或写者才能获得访问权限。
3.3. 公平算法在公平算法中,读者和写者的访问权限是公平的,先到先得。
无论读者还是写者,都需要按照到达的顺序依次获取访问权限。
4. 实验步骤下面是我们实施实验的具体步骤:4.1. 实现基本的读者写者问题解决方案我们首先实现基本的读者写者问题解决方案,包括读者和写者的线程逻辑和共享资源的访问控制。
我们将使用互斥锁和条件变量来保证并发访问的正确性。
4.2. 实现读者优先算法在已有的基本解决方案的基础上,我们实现读者优先算法。
我们将通过优化访问控制的逻辑来实现读者优先的特性。
4.3. 实现写者优先算法类似地,我们在基本解决方案的基础上实现写者优先算法。
我们将调整访问控制的逻辑,使得写者优先于其他读者和写者。
4.4. 实现公平算法最后,我们实现公平算法。
我们将结合队列和条件变量等技术来确保读者和写者的访问顺序是公平的。
操作系统 读者与写者 课程设计报告
操作系统课程设计报告课程设计题目:读者与写者问题学生姓名:汪杰专业:信息安全方向班级:1232102学号:201230210205指导教师:周跃文小组成员:汪杰、聂庆添、刘洋2014年6月10日目录一设计概述……………………………………………………错误!未定义书签。
二设计目的与内容 (4)三设计分析 (5)四程序实现 (6)五程序调试 (7)六结果分析和讨论 (7)七心得体会 (8)八源代码 (8)一设计概述所谓读者写者问题,是指保证一个writer进程必须与其他进程互斥地访问共享对象的同步问题。
读者写者问题可以这样的描述,有一群写者和一群读者,写者在写同一本书,读者也在读这本书,多个读者可以同时读这本书,但是,只能有一个写者在写书,并且,读者必写者优先,也就是说,读者和写者同时提出请求时,读者优先。
当读者提出请求时需要有一个互斥操作,另外,需要有一个信号量S来当前是否可操作。
信号量机制是支持多道程序的并发操作系统设计中解决资源共享时进程间的同步与互斥的重要机制,而读者写者问题则是这一机制的一个经典范例。
与记录型信号量解决读者—写者问题不同,信号量机制它增加了一个限制,即最多允许RN个读者同时读。
为此,又引入了一个信号量L,并赋予初值为RN,通过执行wait(L,1,1)操作,来控制读者的数目,每当有一个读者进入时,就要执行wait(L,1,1)操作,使L的值减1。
当有RN个读者进入读后,L便减为0,第RN+1 个读者要进入读时,必然会因wait (L,1,1)操作失败而堵塞。
对利用信号量来解决读者—写者问题的描述如下:Var RN integer;L,mx:semaphore: =RN,1;BeginParbeginReader :beginRepeatSwait(L,1,1);Swait(mx,1,0);.Perform reader operation;Ssignal(L,1);Until false;EndWriter :beginRepeatSwait(mx ,1,1,l,RN,0);Perform writer operation;Ssignal(mx,1);Until false;EndParendEnd其中,Swait(mx,1,0)语句起着开关作用,只要无Writer进程进入些,mx=1,reader 进程就都可以进入读。
操作系统实验报告_读者写者问题
void WP_WriterThread(void * p) //---------------------------写者优先--写者线程
{
HANDLE h_Mutex1;//互斥变量
h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutexl");
HANDLE h_Mutex2;
h_Mutex2 = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex2");
DWORD wait_for_mutex1; //等待互斥变量所有权
};
void RP_ReaderThread(void * p) //---------------------------读者优先--读者线程
{
HANDLE h_Mutex;//互斥变量
//OpenMutex函数功能:为现有的一个已命名互斥体对象创建一个新句柄
h_Mutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE,"mutex_for_readcount");
(附注释)
#include "stdafx.h"
#include"windows.h"
#include<conio.h>
#include<stdlib.h>
#include<fstream.h>
#include<io.h>
#include<string.h>
#include<stdio.h>
#define READER 'R' //读者
操作系统课程设计报告
青岛理工大学操作系统课程设计报告院(系):计算机工程学院专业:计算机科学与技术专业学生姓名:__杨晓玉班级:__计算093__学号: 200907195 题目:采用“读写平等”策略演示“读者-写者”问题起迄日期:2012-7-2 至2012-7-13___设计地点:网络中心计算机学院机房指导教师:王金龙2011—2012年度第 2 学期完成日期: 2012 年 7 月 13日一、课程设计目的进行操作系统课程设计主要是在学习操作系统课程的基础上,在完成操作系统各部分实验的基础上,对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理功能的认识,还能进一步分析各个部分之间的联系,最后达到对完整系统的理解。
同时,可以提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力、创新能力及团队组织、协作开发软件的能力;还能提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。
此次实验我选择的是经典的读者写者问题。
读写者问题的传统解决方案采用读优先策略,可能会造成后续的写者被随后而来的读者插队而长时间等待,直到全部读者进程运行完毕后,才可进行写操作。
为此,选择采用“读写平等策略”解决读写者问题,希望通过此次课程设计实现读写者的公平竞争,加深对线程、进程及同步概念的理解。
通过研究经典的进程同步问题,实现对读者-写者问题的并发控制,掌握运用信号量解决“同类进程多次访问,而不同类的进程必须互斥访问资源”的控制问题。
此次实验我选择用比较大众的jAVA语言编写,通过自学JAVA语言实现读者写者问题,还提供了我进一步学习编程语言的机会。
二、课程设计内容与要求1、设计内容:通过研究经典的进程同步问题,实现对读者-写者问题的并发控制。
2、说明:阅览室一次最多可以容纳20个人。
3、设计要求:1)读者与写者至少包括ID、进入内存时间、读写时间三项内容,可在界面上进行输入。
2)读者与写者均有二个以上,可在程序运行期间动态增加读者与写者。
“读写平等”策略的“读者--写者”问题实验报告
淮北师范大学程序设计课程设计采用“读写平等”策略的“读者--写者”问题学院计算机科学与技术专业计算机科学与技术(师范)学号 ***********学生姓名 ***指导教师姓名 ***2012年6月16 日一、设计目的与内容课程设计的目的:操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决问题的机会。
●进一步巩固和复习操作系统的基础知识。
●培养学生结构化程序、模块化程序设计的方法和能力。
●提高学生调试程序的技巧和软件设计的能力。
●提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能力。
设计内容:用高级语言编写和调试一个采用“读写平等”策略的“读者—写者”问题的模拟程序。
设计的要求:1.读者与写者至少包括ID、进入内存时间、读写时间三项内容,可在界面上进行输入。
2.读者与写者均有两个以上,可在程序运行期间进行动态增加读者与写者。
3.可读取样例数据(要求存放在外部文件中),进行读者/写者、进入内存时间、读写时间的初始化。
4.要求将运行过程用可视化界面动态显示,可随时暂停,查看阅览室中读者/写者数目、读者等待队列、读写时间、等待时间。
5.读写策略:读写互斥、写写互斥、读写平等(严格按照读者与写者到达的顺序进入阅览室,有写着到达,则阻塞后续到达的读者;有读者到达,则阻塞后续到达的写者)。
有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间,甚至可以是一组处理器寄存器。
有一些只读取这个数据区的进程(reader)和一些只往数据区中写数据的进程(writer)。
以下假设共享数据区是文件。
这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。
这些条件具体来说就是:(1)任意多的读进程可以同时读这个文件;(2)一次只允许一个写进程往文件中写;(3)如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;(4)写进程执行写操作前,应让已有的写者或读者全部退出。
操作系统实验 读者写者问题
《计算机操作系统》实验报告题目读者写者问题学院(部)信息学院专业计算机科学与技术班级学生姓名学号指导教师(签字)一、问题描述一个数据文件或者记录,可以被多个进程共享,我们把只要求读该文件的进程称为“Reader进程”,其他进程则称为“Writer进程”。
允许多个进程同时读一个共享对象,因为读操作不会是数据文件混乱。
但不允许一个Writer进程和其他Reader进程或者Writer进程同时访问共享对象,因为这种访问将会引起混乱。
所谓“读者——写着问题(Reader—Writer Problem)”是指保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题二、解决问题为实现Reader与Writer进程间在读或写是的互斥而设置了一个互斥的信号量Wmutex。
另外,在设置一个整型变量Readcount表示正在读的进程数目。
由于只要有一个Reader进程在读,便不允许Writer去写。
因此,仅当Readercount=0时,表示尚无Reader进程在读时,Reader进程才需要进行Wait(wmutex)操作。
若Wait(Wmutex)操作成功,Reader进程便可去读,相应地,做Readcount+1操作。
同理,仅当Reader进程在执行了Readercount-1操作后其值为0时,才执行Signal(Wmutex)操作,以便让Writer进程写。
又因为Readercount是一个可被多个Reader进程访问的临界资源,因此也应该为它设置一个互斥信号量rmutex。
三、代码实现1、读者优先#include<iostream>#include<Windows.h>using namespace std;CRITICAL_SECTION rmutex,wmutex;int wr;int readernum;DWORD WINAPI reader(LPVOID IpParamter){cout<<"读者申请\n";wr++;EnterCriticalSection(&rmutex);if(readernum==0)EnterCriticalSection(&wmutex);readernum++;cout<<"读者进入成功正在读取\n";LeaveCriticalSection(&rmutex);Sleep(2000);EnterCriticalSection(&rmutex);readernum--;cout<<"读者退出\n";wr--;if(readernum==0)LeaveCriticalSection(&wmutex);LeaveCriticalSection(&rmutex);return 0;}DWORD WINAPI writer(LPVOID PM){cout<<"写者申请\n";while(wr!=0){}EnterCriticalSection(&wmutex);cout<<"写者已进入正在写入\n";Sleep(500);cout<<"写者退出\n";LeaveCriticalSection(&wmutex);return 0;}int main(){readernum=0;wr=0;InitializeCriticalSection(&rmutex);InitializeCriticalSection(&wmutex);HANDLE hr[5];//定义读者线程HANDLE hw[5];//定义写者线程//int thnum;int drn=0; //输入的读者个数int dwn=0; //输入的写者个数cout<<"输入读者写者线程1代表读者2代表写者0代表结束"<<endl;int th[10];int num=0;cin>>th[num];while(th[num]){if(th[num]==1){drn++;}if(th[num]==2){dwn++;}num++;cin>>th[num];}int hr1=0,hw1=0;for(int j=0;j!=num;j++){if(th[j]==1){hr[hr1]=CreateThread(NULL,0,reader,NULL,0,NULL);hr1++;}if(th[j]==2){hw[hw1]=CreateThread(NULL,0,writer,NULL,0,NULL);hw1++;}}WaitForMultipleObjects(drn, hr, TRUE, INFINITE);WaitForMultipleObjects(dwn, hw, TRUE, INFINITE);for(int i=0;i!=drn;i++){CloseHandle(hr[i]);}for(int i=0;i!=dwn;i++){CloseHandle(hw[i]);}DeleteCriticalSection(&rmutex);DeleteCriticalSection(&wmutex);return 0;}2、写者优先#include<iostream>#include<Windows.h>using namespace std;CRITICAL_SECTION rmutex,wmutex;int ww;int readernum;DWORD WINAPI reader(LPVOID IpParamter){cout<<"读者申请\n";while(ww!=0){}EnterCriticalSection(&rmutex);if(readernum==0){EnterCriticalSection(&wmutex);}cout<<"读者进入成功正在读取\n";readernum++;LeaveCriticalSection(&rmutex);Sleep(2000);EnterCriticalSection(&rmutex);readernum--;if(readernum==0)LeaveCriticalSection(&wmutex);cout<<"读者退出\n";LeaveCriticalSection(&rmutex);return 0;}DWORD WINAPI writer(LPVOID PM){ww++;cout<<"写者申请\n";EnterCriticalSection(&wmutex);cout<<"写者已进入正在写入\n";Sleep(1000);cout<<"写者退出\n";ww--;LeaveCriticalSection(&wmutex);return 0;}int main(){readernum=0;ww=0;InitializeCriticalSection(&rmutex);InitializeCriticalSection(&wmutex);HANDLE hr[5];//定义读者线程HANDLE hw[5];//定义写者线程int drn=0; //输入的读者个数int dwn=0; //输入的写者个数cout<<"输入读者写者线程1代表读者2代表写者0代表结束"<<endl;int th[10];int num=0;cin>>th[num];while(th[num]){if(th[num]==1){drn++;}if(th[num]==2){dwn++;}num++;cin>>th[num];}int hr1=0,hw1=0;for(int j=0;j!=num;j++){if(th[j]==1){hr[hr1]=CreateThread(NULL,0,reader,NULL,0,NULL);Sleep(10);hr1++;}if(th[j]==2){hw[hw1]=CreateThread(NULL,0,writer,NULL,0,NULL);Sleep(10);hw1++;}}WaitForMultipleObjects(drn, hr, TRUE, INFINITE);WaitForMultipleObjects(dwn, hw, TRUE, INFINITE);for(int i=0;i!=drn;i++){CloseHandle(hr[i]);}for(int i=0;i!=dwn;i++){CloseHandle(hw[i]);}DeleteCriticalSection(&rmutex);DeleteCriticalSection(&wmutex);return 0;}3、执行结果读者优先在读者优先中先两个读者申请,再一个写者申请,再有两个读者申请。
操作系统读者写者问题报告
操作系统读者写者问题报告
读者写者问题是一种典型的操作系统同步问题,其描述如下:有多个读者和写者同时访问共享资源,读者可以同时访问共享资源,但写者必须独占式的访问共享资源,即任何时刻只能有一个写者访问共享资源,且在写者访问共享资源的期间,任何读者都不得访问共享资源。
此外,读者在访问共享资源时不会修改共享资源,而写者则会对共享资源进行修改。
如何实现读者写者问题呢?简单来说,可以使用信号量机制来解决这个问题。
具体来说,可以使用两个信号量RdMutex和WrMutex,RdMutex用于锁定读者,在读者访问共享资源时,需要申请RdMutex信号量,如果有写者在访问共享资源,则RdMutex会阻止读者访问共享资源;而当最后一个读者结束访问共享资源时,需要释放RdMutex信号量,以便让其他等待的读者访问共享资源。
类似地,WrMutex用于锁定写者,在写者访问共享资源时,需要申请WrMutex信号量,如果有其他读者或者写者在访问共享资源,则WrMutex会阻止写者访问共享
资源;而当写者访问共享资源结束时,需要释放WrMutex信号量,以便让其他等待的写者访问共享资源。
除了信号量机制之外,还可以使用其他同步机制来解决读者写者问题,比如互斥量、条件变量等。
同时,操作系统还可以采用优化策略,比如写优先、读写优先等,来提高读写效率。
总之,读者写者问题是操作系统同步问题中的一个经典问题,其实现方式需要考虑多方面的因素,包括并发访问、同步机制、优化策略等,需要经过深入思考和有效实践才能得到较好的解决方案。
操作系统读者与写者问题课程设计报告
课程设计任务书目录一、课程设计目的及要求 (1)二、相关知识 (1)三、题目分析 (2)四、概要设计 (4)五、代码及流程 (5)六、运行结果 (11)七、设计心得 (12)八、参考文献 (12)一、课程设计目的及要求读者与写者问题(进程同步问题)用n 个线程来表示n个读者或写者。
每个线程按相应测试数据文件的要求,进行读写操作。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制:1)写-写互斥;2)读-写互斥;3)读-读允许;写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
二、相关知识Windows API:在本实验中涉及的API 有:1线程控制:CreateThread 完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函数;它的返回值为所创建线程的句柄。
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, // SDDWORD dwStackSize, // initial stack sizeLPTHREAD_START_ROUTINE lpStartAddress, // threadfunctionLPVOID lpParameter, // thread argumentDWORD dwCreationFlags, // creation optionLPDWORD lpThreadId // thread identifier);2 ExitThread 用于结束当前线程。
VOID ExitThread(DWORD dwExitCode // exit code for this thread);3Sleep 可在指定的时间内挂起当前线程。
VOID Sleep(DWORD dwMilliseconds // sleep time);4信号量控制:WaitForSingleObject可在指定的时间内等待指定对象为可用状态;DWORD WaitForSingleObject(HANDLE hHandle, // handle to objectDWORD dwMilliseconds // time-out interval);hHandle为等待的对象,也就是实现同步或者互斥的对象。
读者写者实验报告
操作系统原理实验报告实验名称:操作系统姓名: XXX学号: xxxxxxxxxx班级: xxx指导老师: xxx一、实验内容在Windows2000环境下,创建一个控制台进程,此进程包含n个线程。
用这n个线程来表示n个读者或写者。
每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。
用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制(包括读者优先和写者优先):1)写-写互斥,即不能有两个写者同时进行写操作。
2)读-写互斥,即不能同时有一个线程在读,而另一个线程在写。
,3)读-读允许,即可以有一个或多个读者在读。
读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。
二、实验目的在Windows2000环境下,创建一个控制台进程,此进程包含n个线程。
用这n 个线程来表示n个读者或写者。
每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。
用信号量机制分别实现读者优先和写者优先的读者-写者问题。
三、实验原理1).读者优先读者优先指的是除非有写者在写文件,否则读者不需要等待。
所以可以用一个整型变量read_count记录当前的读者数目,用于确定是否需要释放正在等待的写者线程(当read_count=O时,表明所有的读者读完,需要释放写者等待队列中的一个写者)。
每一个读者开始读文件时,必须修改read_count变量。
因此需要一个互斥对象mutex来实现对全局变量read_count修改时的互斥。
另外,为了实现写-写互斥,需要增加一个临界区对象write。
操作系统读者写者实验报告
《操作系统原理》课程设计课程设计起止时间:2009年11月30日至12月11日指导教师:成绩:课程设计成绩评定表一.设计说明(四号,宋体,加粗)通过学习操作系统,与之前的语句基础相结合,用C语言来编写读者写着问题。
读者写者问题(read—write problem)是一个经典的并发程序设计问题。
有两组并发进程:读者和写者,共享一个问题F,要求:(1)允许多个读者可同时对之执行读操作;(2)只允许一个写者往文件中写信息;(3)任一写者在完成写操作之前不允许其他读者或者写者工作;(4)写者执行写操作前,应让已有的写者和读者全部退出。
二.工作原理(四号,宋体,加粗)读者和写者问题是典型是经典的进程同步问题,进程同步任务是使并发的诸进程之间有效的共享资源,相互合作,从而保证程序的可再现性。
在读者—写者问题中,允许多个读者同时读一个数据对象,因为读文件不会使数据发生混乱,但绝不允许一个写者进程与其他读者进程或写者进程同时访问该数据对象。
文件是诸进程能互斥访问临界资源,读者进程和写者进程,写者进程和写者进程之间的互斥。
在读者进程中,可以有多个读者在读数据库,在读者进程的计数要互斥,以免发生错误,同时注意当第一个读者进程读时,一定要封锁写者进程。
当读者进程逐渐撤离时,也要针对计数变量进行互斥操作,若当前为最后一个读者进程时,读完后,则唤醒写者进程。
当写者进程在进行写操作时,可以封锁其他读者或写者进程,当写操作完成时,唤醒其他读者或写者进程。
所以分析了以下4种可能发生的情况:第 1 种情况: 读者的优先权比写者高,而且,不用调配。
所有读者的优先权都比写者的优先权高,而且,不用调配。
一个读者需要等待的唯一情况是,一个写者已经占用了文件。
一个写者可以取得文件的条件是,没有一个读者处在等待状态或正在读文件。
允许读者们结盟,以便能长期占用文件,而禁止写者的写。
第 2 种情况: 在一个读者已经占有了文件的时候,全体读者的优先权才比写者高。
操作系统原理课程设计读者-写者问题的实现
*******************实践教学*******************计算机与通信学院2012年秋季学期操作系统原理课程设计题目:读者-写者问题的实现专业班级:姓名:学号:指导教师:成绩:目录摘要 (2)1.设计思想 (3)2.各模块的伪码算法 (4)3. 函数关系调用图 (6)4.程序测试结果 (7)设计总结 (10)参考文献 (11)致谢 (12)摘要本设计的读者写者问题,是指一些进程共享一个数据区。
数据区可以使一个文件、一块内存空间或者一组寄存器。
Reader进程只能读数据区中的数据,而writer进程必须与其他进程互斥地访问共享对象的同步问题。
读者写者问题可以这样的描述, 有一群写者和一群读者, 写者在写同一本书, 读者也在读这本书, 多个读者可以同时读这本书。
但是,只能有一个写者在写书, 并且,读者必写者优先,也就是说,读者和写者同时提出请求时,读者优先。
当读者提出请求时需要有一个互斥操作, 另外, 需要有一个信号量S来确定当前是否可操作。
本设计方案就是通过利用记录型信号量对读者写者问题的解决过程进行模拟演示,形象地阐述记录型信号量机制的工作原理。
关键词:共享对象,互斥,同步,信号量1.设计思想本设计借助C语言实现进程同步和互斥的经典问题--读者写者问题,用高级语言编写和调试一个进程同步程序,以加深对进程同步机制的理解。
通过用C 语言模拟进程同步实现,加深理解有关进程同步和互斥机制的概念及P、V操作的应用。
学生通过该题目的设计过程,掌握读者、写者问题的原理、软件开发方法并提高解决实际问题的能力。
在 Windows环境下,创建一个包含n个线程的控制台进程。
用这n个线每个线程按相应测试数据文件的要求,进行读写操作。
程来表示 n 个读者或写者。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。
读者写者问题操作系统课程设计
某某大学课程设计报告课程名称:操作系统课程设计设计题目:读者写者问题系别:计算机系专业:计算机科学与技术组别:第四组学生姓名: 某某某学号:起止日期:指导教师:目录1、需求分析课程设计题目课程设计题目:读者写者问题课程任务及要求编写程序实现读者写者算法(读_写互斥,读_读允许,写写互斥)给出解决方案(包括说明设计实现(de)原理,采用(de)数据结构等)画出程序(de)基本结构框图和流程图分析说明每一部分程序(de)(de)设计思路实现源代码按期提交完整(de)程序代码和可执行程序根据要求完成课程设计报告总结课程设计思想读者-写者问题是一个经典(de)并发程序设计问题.有两组并发进程:读者和写者,共享文件F,要求:(1)允许多个读者同时对文件执行读操作;(2)只允许一个写者对文件执行写操作;(3)任何写者在完成写操作之前不允许其他读者或写者工作;(4)写者在执行写操作前,应让已有(de)写者和读者全部退出.单纯使用信号量不能解决此问题,必须引入计数器readcount对读进程记数.为了有效(de)解决读者写者问题,需要引进读者-写者锁,允许多名读者同时以只读(de)方式存取有锁保护(de)对象;或一位写者以写方式存取有锁保护(de)对象.当一名或多名读者上锁后,此时形成读锁,写者将不能访问有锁保护(de)对象;当锁被请求者用于写操作时,形成写锁,其他进程(de)读写操作必须等待.软硬件运行环境及开发工具本课程设计在windows操作系统下,使用java语言完成(de).2、概要设计程序流程图本系统主要有读者和写者两类对象,所以系统主要针对(de)是这两类对象(de)操作.读者类对象(de)流程图如下:图读者类对象写者类对象(de)流程图如下:图写者类对象所用原理并发原理进程(de)并发是指一组进程(de)执行在时间上重叠(de),所谓(de)时间重叠是指一个进程执行第一条指令是在另一个进程执行完最后一条指令之前开始(de).并发(de)实质是处理器在几个进程之间(de)多路复用,并发是对有限物理资源强制行使多用户共享,消除计算机部件之间(de)互等现象,提高系统资源(de)利用率.并发进程可能是无关(de),也可能是交互(de).进程(de)交互必须是有控制(de),否则会出现不正确(de)计算结果.互斥操作原理互斥是指若干进程因互相争夺独占型资源而产生(de)竞争制约关系.并发进程中与共享变量有关(de)程序段称为“临界区”,共享变量所代表(de)资源称为“临界资源”,临界区必须以一种相对于其他进程而言互相排斥(de)方式执行.如果能够保证一个进程在临界区执行时,不让另一个进程进入相同(de)临界区,即各进程对共享变量(de)访问是互斥(de),那么,就不会引发与时间有关(de)错误.而为了正确而有效地使用临界资源,共享变量(de)并发进程应遵守临界区调度(de)三个原则:一次至多有一个进程进入临界区内执行;如果已有进程在临界区中,试图进入临界区(de)其他进程应等待;进入临界区内进程应在有限时间内退出,以便让等待队列中(de)一个进程进入.总结起来有三句话:互斥使用,有空让进;忙则等待,有限等待;择一而入,算法可行.面向对象编程编程原理面向对象是一种新兴(de)程序设计方法,或者说它是一种新(de)程序设计范型,其基本思想是使用对象,类,继承,封装,消息等基本概念来进行程序设计.它是从现实世界中客观存在(de)事物(即对象)出发来构造软件系统,并在系统构造中尽可能运用人类(de)自然思维方式,强调直接以问题域(现实世界)中(de)事物为中心来思考问题,认识问题,并根据这些事物(de)本质特点,把他们抽象地表示为系统中(de)对象,作为系统(de)基本构成单位(而不是用一些与现实世界中(de)事物相关比较远,并且没有对应关系(de)其他概念来构造系统).这可以使系统直接地映射问题域,保持问题域中事物及其相互关系(de)本来面貌.本课程设计中涉及了两个对象,因此用面向对象(de)语言来编程是适合(de).我们这次用到了Java语言.锁机制原理为了解决读者和写者之间(de)同步互斥问题,在本课程设计中要用到Java中(de)锁机制,这样会给编程带来很大(de)方便.多线程同步(de)实现最终依赖锁机制.我们可以想象某一共享资源是一间屋子,每个人都是一个线程.当A希望进入房间时,他必须获得门锁,一旦A获得门锁,他进去后就立刻将门锁上,于是B,C,D...就不得不在门外等待,直到A释放锁出来后,B,C,D...中(de)某一人抢到了该锁(具体抢法依赖于JVM(de)实现,可以先到先得,也可以随机挑选),然后进屋又将门锁上.这样,任一时刻最多有一人在屋内(使用共享资源). Java语言规范内置了对多线程(de)支持.对于Java程序来说,每一个对象实例都有一把“锁”,一旦某个线程获得了该锁,别(de)线程如果希望获得该锁,只能等待这个线程释放锁之后.获得锁(de)方法只有一个,就是synchronized关键字.1.用锁操作原语实现互斥为解决进程互斥进人临界区(de)问题,可为每类临界区设置一把锁,该锁有打开和关闭两种状态,进程执行临界区程序(de)操作按下列步骤进行:①关锁.先检查锁(de)状态,如为关闭状态,则等待其打开;如已打开了,则将其关闭,继续执行步骤②(de)操作.②执行临界区程序.③开锁.将锁打开,退出临界区.2.WAIT,NOTIFY,NOTIFYALL操作原语信号量(de)初值可以由系统根据资源情况和使用需要来确定.在初始条件下信号量(de)指针项可以置为0,表示队列为空.信号量在使用过程中它(de)值是可变(de),但只能由WAIT,SIGNAL操作来改变.设信号量为S,对S(de)WAIT操作记为WAIT(S),对它(de)SIGNAL操作记为SIGNAL(S).WAIT(S):顺序执行以下两个动作:1)信号量(de)值减1,即S=S-1;2)如果S≥0,则该进程继续执行;如果 S<0,则把该进程(de)状态置为阻塞态,把相应(de)WAITCB连人该信号量队列(de)末尾,并放弃处理机,进行等待(直至其它进程在S上执行SIGNAL操作,把它释放出来为止).SIGNAL(S):顺序执行以下两个动作线程(de)原理线程是进程中(de)实体,一个进程可以拥有多个线程,一个线程必须有一个父进程.线程不拥有系统资源,只有运行必须(de)一些数据结构;它与父进程(de)其它线程共享该进程所拥有(de)全部资源.线程可以创建和撤消线程,从而实现程序(de)并发执行.一般,线程具有就绪、阻塞和运行三种基本状态.读者写者问题(de)一般应用读者写者是典型(de)并发程序设计问题,它(de)方法可以普遍用于多线程(de)同步互斥问题,对于共享资源出现(de)问题做出了很好(de)解决,使得事物并发(de)效率更高,类似(de)问题还有生产者-消费者问题,理发师问题等等.3、详细设计本次课程设计采用(de)是java语言编写,所以要用到类,包括读者类和写者类,它们都是继承(de)线程Thread类,在主程序中创建类对象(读者对象和写者对象),用线程来实现并发读者类对象和写者类对象(de)公共属性包括:private static final int NAP_TIME=5;private int readerCount;private int writerCount;private boolean dbReading;private boolean dbWriting;通过NAP_TIME调整线程随机休息时间通过readercount和writercount来记录读者和写者线程(de)个数通过dbreading和dbwriting来判断读者和写者(de)状态,其中读者是靠判断writercount>0来实现读写互斥(de),同时允许读读同步;而写者是靠判断dbreading=true||dbwriting=true来实现读写互斥和写写互斥(de).读写等待是随机(de),运用(de)是()函数程序代码如下:class Database{/读者写者公用(de)资源Database类/private static final int NAP_TIME=5;private int readerCount; /记录当前(de)读者个数/private int writerCount; /记录当前(de)写者个数/private boolean dbReading; /显示是否有读者在读/private boolean dbWriting; /显示是否有写者在写/public Database() {/构造函数/super();readerCount=0;writerCount=0;dbReading=false;dbWriting=false;Count="+readerCount);return readerCount;}public synchronized void startWriting(){++writerCount;while(dbReading==true||dbWriting==true){/如果有读者在读或者有写者在写,那么写者进行等待/ try{"Writer is waiting");wait();}catch(Exception e){}}dbWriting =true; /有写者在写,则设置写状态为true/}public synchronized void endWriting(){--writerCount;/由于每次只有一个写者在写,所以结束写操作后写者个数一定为0/ dbWriting=false; /没有写者写,则设置写状态为false/"one writer is done writing. Count="+writerCount);notifyAll(); /释放所有等待(de)线程/}}class Reader extends Thread{ /建立读者类/private Database server;private int readerNum;public Reader(int r,Database db) {super();readerNum=r;server=db;}public void run(){while(true){"reader "+readerNum+" is sleeping");();"reader "+readerNum+" wants to read");c=();"reader "+readerNum+" is reading. Count="+c);();c=();"It is reader "+readerNum+" who has done reading according to count="+c);}}}class Writer extends Thread{ /建立写者类/private Database server;private int writerNum;public Writer(int w,Database db) {writerNum=w;server=db;}public void run(){while(true){"Writer "+writerNum+" is sleeping");();"Writer "+writerNum+" wants to write");();"Writer "+writerNum+" is writing");();();"It is Writer "+writerNum+" who has done writing ."); }}}public class DatabaseServer {public DatabaseServer() {}public static void main(String[] args) { Database db=new Database();/建立四个读者对象和两个写者对象/Reader r1=new Reader(1,db);Reader r2=new Reader(2,db);Reader r3=new Reader(3,db);Reader r4=new Reader(4,db);Writer w1=new Writer(1,db);Writer w2=new Writer(2,db);();();();();();();}}4、调试与操作说明由于读写等待是随机(de)所以可能出现多中情况,读写(de)顺序可能会不一样,以下是几种不同(de)运行结果:图读者写者结果一上图中(de)结果说明:按照读者1、读者2、读者3、写者1、读者4、写者2……(de)顺序进入,最终(de)执行结果按写者1、写者2、读者2、4、3、1……(de)顺序进行.图读者写者结果二上图中(de)结果说明:按照读者1、读者3、读者2、写者1……(de)顺序进入,最终(de)执行结果按读者3、读者1、写者2……(de)顺序进行.5、课程设计总结与体会通过集体(de)努力,这次课程设计基本上可以完成功能了,读_写互斥,读_读允许,写写互斥能够实现了,但是还存在一些不足(de)地方,比如不能够实现读者优先或者写者优先,可能出现长时间等待(de)情况,在这次课程设计后,我们会继续努力将功能完善.这次我们(de)收获就是懂得了使用Java这样(de)面向对象(de)语言来实现线程同步互斥问题,知道了Java中(de)锁机制,这对以后(de)编程有很大(de)帮助,同时也进一步加深了对操作系统这类问题(de)理解.6、致谢感谢一学期来老师给我们(de)教导,让我们对操作系统有了整体(de)理解,这对我们以后(de)学习有很大(de)帮助,对于这次课程设计,老师也给了我们充分(de)支持和理解,是您对我们(de)指导帮助我们能够顺利(de)完成这次课程设计.7、参考文献[1]费翔林,骆斌. (第4版)[M]. 北京: 高等教育出版社, 2009.[2]李尊朝,苏军.Java语言程序设计(第二版)[M].中国铁道出版社,2008.。
读者写者问题
操作系统课程设计报告附代码:#include<iostream>#include<stdlib.h>#include<stdio.h>#include<fstream>#include<Windows.h>#define INTE_PER_SEC 1000 //每秒时钟中断的数目#define MAX_THREAD_NUM 64 //最大线程数目using namespace std;//变量声明初始化int readercount = 0;//记录等待的读者数目int writercount = 0;//记录等待的写者数目//定义句柄类型变量HANDLE rc1_mutex;//因读者数量而添加的互斥信号量,用于读者优先HANDLE rc2_mutex;//因读者数量而添加的互斥信号量,用于写者优先HANDLE wc_mutex;//因写者数量而添加的互斥信号量HANDLE book;//互斥访问信号量HANDLE wrt;//保证每次只有一个写者进行写操作HANDLE mutex;//避免写者同时与多个读者进行竞争//定义线程结构struct threadInfo{int serial; //线程序号char entity; //线程类别(R/W)double delay; //线程延迟时间double persist; //线程读写操作持续时间};/**********************读者优先***********************************/ //进程管理-读者线程void rp_threadReader(void *p){//windows数据类型-双字节//延迟时间DWORD m_delay;//读文件持续时间DWORD m_persist;//线程序号int m_serial;//变量赋值m_serial = ((threadInfo*)(p))->serial;m_delay = (DWORD)(((threadInfo*)(p))->delay*INTE_PER_SEC);m_persist = (DWORD)(((threadInfo*)(p))->persist*INTE_PER_SEC);//等待-延迟时间Sleep(m_delay);cout<<"读者线程"<<m_serial<<"申请."<<endl;//对readercount互斥访问WaitForSingleObject(rc1_mutex, -1);//第一位读者-申请互斥访问变量if (readercount == 0) WaitForSingleObject(book, -1);readercount++;//释放互斥信号量rc1_mutexReleaseSemaphore(rc1_mutex, 1, NULL);cout<<"读者线程"<<m_serial<<"开始."<<endl;//读者持续时间Sleep(m_persist);cout<<"读者线程"<<m_serial<<"结束."<<endl;//修改readercountWaitForSingleObject(rc1_mutex, -1);//读者读完,readercount减1readercount--;//释放书籍,可以允许写者if (readercount==0) ReleaseSemaphore(book, 1, NULL);//释放互斥信号量rc1_mutexReleaseSemaphore(rc1_mutex, 1, NULL);}/*****************///进程管理-写者线程void rp_threadWriter(void *p){//延迟时间DWORD m_delay;//写文件持续时间DWORD m_persist;//线程序号int m_serial;//变量赋值m_serial = ((threadInfo*)(p))->serial;m_delay = (DWORD)(((threadInfo*)(p))->delay*INTE_PER_SEC);m_persist = (DWORD)(((threadInfo*)(p))->persist*INTE_PER_SEC);//等待-延迟时间Sleep(m_delay);cout<<"写者线程"<<m_serial<<"申请."<<endl;//申请资源WaitForSingleObject(book, INFINITE);cout<<"写者线程"<<m_serial<<"开始."<<endl;//写者持续时间Sleep(m_persist);cout<<"写者线程"<<m_serial<<"结束."<<endl;//释放互斥访问信号量ReleaseSemaphore(book, 1, NULL);}/*****************///读者优先void ReaderPriority(char *file){//线程数目DWORD threadNum = 0;//线程序号DWORD threadSerial;//等待所有线程结束DWORD waitForAll;//创建信号量//读者对count修改互斥信号量,初值为1,最大为1rc1_mutex = CreateSemaphore(NULL, 1, 1, "mutexForReadcount");//书籍互斥访问信号量,初值为1,最大值为1book = CreateSemaphore(NULL, 1, 1, NULL);//线程句柄,线程对象的数组HANDLE threadArray[MAX_THREAD_NUM];threadInfo threadInfo[MAX_THREAD_NUM];//初始化readcountreadercount = 0;ifstream f;f.open(file);cout << "读者优先:" << endl;while (f){//读入每一个读者,写者的信息f >> threadInfo[threadNum].serial;f >> threadInfo[threadNum].entity;f >> threadInfo[threadNum].delay;f >> threadInfo[threadNum++].persist;f.get();}for (int i = 0; i<(int)(threadNum); i++){if (threadInfo[i].entity == 'R'){//创建读者线程threadArray[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(rp_threadReader), &threadInfo[i], 0, &threadSerial);}else{//创建写者线程threadArray[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(rp_threadWriter), &threadInfo[i], 0, &threadSerial);}}//等待子线程结束//关闭句柄waitForAll = WaitForMultipleObjects(threadNum, threadArray, TRUE, -1);cout<<endl<<"所有读者写者已经完成操作"<<endl;//关闭句柄for(int i = 0; i<(int)(threadNum); i++) CloseHandle(threadArray[i]);CloseHandle(rc1_mutex);CloseHandle(book);}/*************************写者优先********************************///进程管理-读者线程void wp_threadReader(void *p){//延迟时间DWORD m_delay;//读文件持续时间DWORD m_persist;//线程序号int m_serial;//变量赋值m_serial = ((threadInfo*)(p))->serial;m_delay = (DWORD)(((threadInfo*)(p))->delay*INTE_PER_SEC);m_persist = (DWORD)(((threadInfo*)(p))->persist*INTE_PER_SEC);//等待-延迟时间Sleep(m_delay);cout<<"读者线程"<<m_serial<<"申请."<<endl;WaitForSingleObject(mutex, -1);WaitForSingleObject(book, -1);//对readercount需要互斥访问WaitForSingleObject(rc2_mutex, -1);//第一位读者-申请book互斥访问信号量,防止写者进行写操作if(readercount == 0) WaitForSingleObject(wrt, -1);//readercount数量加1readercount++;//释放互斥信号量rc2_mutexReleaseSemaphore(rc2_mutex, 1, NULL);//释放互斥信号量bookReleaseSemaphore(book, 1, NULL);//释放互斥信号量mutexReleaseSemaphore(mutex, 1, NULL);cout<<"读者线程"<<m_serial<<"开始."<<endl;//读者持续时间Sleep(m_persist);cout<<"读者线程"<<m_serial<<"结束."<<endl;//修改readercountWaitForSingleObject(rc2_mutex, -1);//读者读完,readercount减1readercount--;//释放资源,可以允许写者if (readercount==0) ReleaseSemaphore(wrt, 1, NULL);//释放互斥信号量rc_mutexReleaseSemaphore(rc2_mutex, 1, NULL);}/*****************///进程管理-写者线程void wp_threadWriter(void *p){//延迟时间DWORD m_delay;//读文件持续时间DWORD m_persist;//线程序号int m_serial;//变量赋值m_serial = ((threadInfo*)(p))->serial;m_delay = (DWORD)(((threadInfo*)(p))->delay*INTE_PER_SEC);m_persist = (DWORD)(((threadInfo*)(p))->persist*INTE_PER_SEC);//等待-延迟时间Sleep(m_delay);cout<<"写者线程"<<m_serial<<"申请."<<endl;//对writercount互斥访问WaitForSingleObject(wc_mutex, -1);//第一位写者申请资源if(writercount==0) WaitForSingleObject(book, -1);//writercount加1writercount++;//释放资源ReleaseSemaphore(wc_mutex, 1, NULL);WaitForSingleObject(wrt, -1);cout<<"写者线程"<<m_serial<<"开始."<<endl;//写文件持续时间Sleep(m_persist);cout<<"写者线程"<<m_serial<<"结束."<<endl;//释放资源ReleaseSemaphore(wrt, 1, NULL);//对writercount互斥访问WaitForSingleObject(wc_mutex, -1);writercount--;//释放资源if(writercount==0) ReleaseSemaphore(book, 1, NULL);//释放资源ReleaseSemaphore(wc_mutex, 1, NULL);}//写者优先void WriterPriority(char *file){//线程数目DWORD threadNum = 0;//线程序号DWORD threadSerial;//等待所有线程结束DWORD waitForAll;//创建信号量//读者对count修改互斥信号量,初值为1,最大为1rc2_mutex = CreateSemaphore(NULL, 1, 1, "mutexForReadercount");//写者对count修改互斥信号量,初值为1,最大为1wc_mutex = CreateSemaphore(NULL, 1, 1, "mutexForWritercount");wrt = CreateSemaphore(NULL, 1, 1, NULL);mutex = CreateSemaphore(NULL, 1, 1, NULL);//书籍互斥访问信号量,初值为1,最大值为1book = CreateSemaphore(NULL, 1, 1, NULL);//线程句柄,线程对象的数组HANDLE threadArray[MAX_THREAD_NUM];threadInfo threadInfo[MAX_THREAD_NUM];//初始化readcountreadercount = 0;writercount = 0;ifstream f;f.open(file);cout << "写者优先:" << endl;while (f){//读入每一个读者,写者的信息f >> threadInfo[threadNum].serial;f >> threadInfo[threadNum].entity;f >> threadInfo[threadNum].delay;f >> threadInfo[threadNum++].persist;f.get();}for (int i = 0; i<(int)(threadNum); i++){if (threadInfo[i].entity == 'R'){//创建读者线程threadArray[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(wp_threadReader), &threadInfo[i], 0, &threadSerial);}else{//创建写者线程threadArray[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(wp_threadWriter), &threadInfo[i], 0, &threadSerial);}}//等待子线程结束//关闭句柄waitForAll = WaitForMultipleObjects(threadNum, threadArray, TRUE, -1);cout<<endl<<"所有读者写者已经完成操作"<<endl;for(int i = 0; i<(int)(threadNum); i++) CloseHandle(threadArray[i]);CloseHandle(wc_mutex);CloseHandle(rc2_mutex);CloseHandle(book);}//主函数int main(){char num;cout << "欢迎进入读者写者模拟程序" << endl;while (true){//打印提示信息cout << "请输入你的选择" << endl;cout << "1、读者优先" << endl;cout << "2、写者优先" << endl;cout << "3、退出程序" << endl;cout << endl;//输入不正确,继续输入do{num = (char)getchar();} while (num != '1'&&num != '2'&&num != '3');//选择1,读者优先if (num=='1') ReaderPriority(const_cast<char *>("thread.txt"));//选择2,写者优先else if (num=='2') WriterPriority(const_cast<char *>("thread.txt"));//选择3,退出else return 0;//结束cout<<endl<<"Press Any Key to Coutinue"<<endl;getchar();getchar();}return 0;}运行结果截屏:读者优先:写者优先:。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
^
课程设计任务书
目录
<
一、课程设计目的及要求 (1)
二、相关知识 (1)
三、题目分析 (2)
四、概要设计 (4)
五、代码及流程 (5)
六、运行结果 (11)
七、设计心得 (12)
八、参考文献 (12)
!
一、课程设计目的及要求
读者与写者问题(进程同步问题)
用n 个线程来表示n个读者或写者。
每个线程按相应测试数据文件的要求,进行读写操作。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
读者-写者问题的读写操作限制:
1)写-写互斥;
2)读-写互斥;
3)读-读允许;
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
二、相关知识
Windows API:
在本实验中涉及的API 有:
1线程控制:
CreateThread 完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函数;它的返回值为所创建线程的句柄。
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes, 何一个读者运行时,都现在rfirst上加1,然后判定他是否取值为1.如果是1,则做P(wrt),否则不做。
(3)判定是否是第一个写者
原理同(2)判定是否为第一个读者。
(4)写者优先问题的解决需要用到的如下的信号量和变量
rsem: 初值为1的互斥信号量,在至少有一个写者准备访问数据时就不允许随后来的读者访问数据
wserm: 初值为1的互斥信号量,之后有一个写者访问数据时其他写者和读者就被阻止对数据的访问
ReadMutex: 创建写者的互斥信号量,初值为1
WriteMutex: 创建读者的互斥信号量,初值为1
z: 初值为1的互斥信号量,在至少有一个写着准备访问数据、且后面已经来一个读者时再来的读者将在这个信号量上等待
rifrrst:读者计数变量,初值为0
wfirst:写者计数变量,初值为0
写者优先的PV原语:
reader(i): {
P(z);
P(rsem);P(ReadMutex); rfirst=rfirst+1; if(rfirst==1)
P(wsem);
V(ReadMutex);
V(rsem);
V(z);
读取所需数据;
P(ReadMutex);
rfirst=rfirst-1;
if(rfirst==0)
V(wsem);
V(ReadMutex);
}
Writer():
{
P(WriteMutex);
wfirst=wfirst+1;
if(wfirst==1)
P(rsem);
V(WritedMutex);
P(wsem);
改写所需数据;
V(wsem);
P(WriteMutex);
wfirst=wfirst-1;
if(wfirst==0)
V(rsem);
V(WriteMutex);
}
读者写者
图读者-写者的完整流程框图
(5)读者优先
与写者优先算法相反,有一个读者优先的算法,即只要有读者在读数据,写者被拒绝在临界区外面,如果有源源不断的写者来,但是只要写者不是第一个,那么写者将会永远被拒绝在临界区外面。
wrt::初值为1的互斥信号量,只要有一个写者访问数据,则其他写者和读者就要被阻止对数据的访问。
mutex:保证读者互斥操作first的信号量,初值为1
first :读者计数变量,初值为0
读者优先的PV原语:
write():
{
P(wrt);
对数据进行修改;
V(wrt);
}read():{
P(mutex);
first = first+1;
if(first == 1)
P(wrt);
V(mutex);
读取所需数据
P(mutex);
first = first+1;
if(first == 0)
V(wrt);
V(mutex);
}
四、概要设计
(1)控制流程
用CheckPersonList(PersonLists)函数检查PersonLists中是否有为创建的进程(读写者)。
如果有则创建相应的读写线程
(2)创建读写者
用bool CreateReader(int StartTime,int WorkTime)函数创建读者写者相应的线程,其中由windows提供的函数为CreateThread(NULL,0,ReaderProc,(LPVOID)pPerson,0,&dwThreadID);返回的是DWORD型变量。
在CreateReader(int StartTime,int WorkTime)中还会初始化相应的读写者的基本信息,例如何时申请数据何时读数据何时关闭线程等等。
(3)读写者进程
参见图读者-写者的完整流程图。
(4)同步与互斥
WaitForSingleObject(信号量名字,infinite)和ReleaseSemaphore(信号量名字,1,null)用于实现同步于互斥,执行WaitForSingleObject(信号量名字,infinite)信号量相应的信号量减1,执行ReleaseSemaphore(信号量名字,1,null)恢复1。
五、代码及流程
.\n",pPerson->ID);
WaitForSingleObject(rsem,INFINITE);.\n",pPerson->ID);
WaitForSingleObject(ReadMutex,INFINITE);.\n",pPerson->ID);
while(CurrentTime < pPerson->StartTime + pPerson->WorkTime) {
.\n",pPerson->ID);
WaitForSingleObject(WriteMutex,INFINITE);.\n",pPerson->ID);
while(CurrentTime < pPerson->StartTime + pPerson->WorkTime) {
C++程序设计课程设计》.北京: 机械工业出版社,2004
[2][美]Abraham Silberschatz, Peter Baer Galvin, Greg Gagne 著. 郑扣根译. 操作
系统概念(第六版). 北京:高等教育出版社,2004
[3]陈向群,向勇等. Windows操作系统原理(第二版). 北京:机械工业出版社,2004. `。