操作系统课设: 实现读者写者(Reader-Writer Problem)问题
操作系统课程设计报告——读者写者问题

操作系统课程设计课题:读者写者问题姓名:赫前进班级: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 个读者或写者。
每个线程按相应测试数据文件(格式见下)的要求进行读写操作。
操作系统课设: 实现读者写者(Reader-Writer Problem)问题

学号:课程设计课程名称操作系统学院计算机科学与技术学院专业软件工程班级姓名指导教师2014——2015学年第1学期1《操作系统原理》课程设计指导书课程编号:课程名称:操作系统/Operating System周数/学分:1周/1学分先修课程:高级语言程序设计、汇编语言、数据结构、计算机组成原理适用专业:计算机科学与技术、软件工程开课学院、系或教研室:计算机科学与技术学院一、课程设计的目的通过对操作系统内核实现代码的阅读、修改、设计,理解和掌握复杂的操作系统的工作原理。
二、课程设计的内容和要求1.系统调用学习在Linux中产生一个系统调用以及怎样通过往Linux内核中增加一个新函数从而在该内核空间中实现对用户空间的读写。
这个函数的功能是返回当前的系统时间。
实验条件要求:每人一台Linux主机且有超级用户权限。
2.内核定时器通过研究内核的时间管理算法学习内核源代码。
然后应用这些知识并且使用“信号”建立一种用户空间机制来测量一个多线程程序的执行时间。
实验条件要求:每人一台Linux主机且有超级用户权限。
3.实现生产者消费者(Bounded – Buffer Problem)问题通过研究Linux的线程机制和信号量实现生产者消费者(Bounded Buffer)问题的并发控制。
实验条件要求:每人一台与Linux主机联网的Windows主机,普通用户权限。
4.实现读者写者(Reader-Writer Problem)问题通过研究Linux的线程机制和信号量实现读者写者(Reader-Writer)问题并发控制。
实验条件要求:每人一台与Linux主机联网的Windows主机,普通用户权限。
三、课程设计进度安排四、课程设计说明书与图纸要求应包含如下内容:1.设计题目与要求2.总的设计思想及系统平台、语言、工具等。
3.数据结构与模块说明(功能与流程图)4.源程序5.运行结果与运行情况6.调试记录7.自我评析和总结五、课程设计评分标准注:优(90-100分)、良(80-89分)、中(70-79分)、及格(60-69分)、60分以下为不及格。
(完整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上。
读者-写者问题解答计算机操作系统实验报告指导资料

2.读者—写者问题读者—写者问题(Readers-Writers problem)也是一个经典的并发程序设计问题,是经常出现的一种同步问题。
计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader);另一些进程则要求修改数据(称为写者Writer)。
就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:(1)允许多个读者同时执行读操作;(2)不允许读者、写者同时操作;(3)不允许多个写者同时操作。
Reader和Writer的同步问题分为读者优先、弱写者优先(公平竞争)和强写者优先三种情况,它们的处理方式不同。
(1)读者优先。
对于读者优先,应满足下列条件:如果新读者到:①无读者、写者,新读者可以读;②有写者等待,但有其它读者正在读,则新读者也可以读;③有写者写,新读者等待。
如果新写者到:①无读者,新写者可以写;②有读者,新写者等待;③有其它写者,新写者等待。
单纯使用信号量不能解决读者与写者问题,必须引入计数器rc 对读进程计数;rc_mutex 是用于对计数器rc 操作的互斥信号量;write表示是否允许写的信号量;于是读者优先的程序设计如下:int rc=0; //用于记录当前的读者数量semaphore rc_mutex=1; //用于对共享变量rc 操作的互斥信号量semaphore write=1; //用于保证读者和写者互斥地访问的信号量void reader() /*读者进程*/do{P(rc_mutex); //开始对rc共享变量进行互斥访问rc ++; //来了一个读进程,读进程数加1if (rc==1) P(write);//如是第一个读进程,判断是否有写进程在临界区,//若有,读进程等待,若无,阻塞写进程V(rc_mutex); //结束对rc共享变量的互斥访问读文件;P(rc_mutex); //开始对rc共享变量的互斥访问r c--; //一个读进程读完,读进程数减1if (rc == 0) V(write);//最后一个离开临界区的读进程需要判断是否有写进程//需要进入临界区,若有,唤醒一个写进程进临界区V(rc_mutex); //结束对rc共享变量的互斥访问} while(1)void writer() /*写者进程*/do{P(write); //无读进程,进入写进程;若有读进程,写进程等待写文件;V(write); //写进程完成;判断是否有读进程需要进入临界区,//若有,唤醒一个读进程进临界区} while(1)读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。
操作系统课程设计 (4)

设计1 题目进程同步(读者-写者问题)一、问题描述与分析一个数据文件或记录,可被多个进程共享,我们把只要求读该文件的进程称为“Reader”进程,其他进程则称为“Writer进程”允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。
但不允许一个Writer进程和其他Reader进程或Writer进程同时访问将会引起混乱。
所谓读者写者问题,是指保证一个writer进程必须与其他进程互斥地访问共享对象的同步问题。
读者写者问题可以这样的描述,有一群写者和一群读者,写者在写同一本书,读者也在读这本书,多个读者可以同时读这本书,但是,只能有一个写者在写书,并且,读者必写者优先,也就是说,读者和写者同时提出请求时,读者优先。
当读者提出请求时需要有一个互斥操作,另外,需要有一个信号量S 来当前是否可操作。
二、设计要求和目的1.设计要求通过解决读者写者问题实现进程同步。
即(1)实现写-写互斥,(2)读-写互斥(3)读-读允许(4)写者优先2. 设计目的(l).用信号量来实现读者写者问题,掌握进程同步机制及其实现机理。
(2).理解和运用信号量、PV原语、进程间的同步互斥关系等基本知识。
三、背景知识1.参考操作系统课本中关于进程同步这方面的知识以及结合老师上课的讲解,仔细研究利用信号量实现读写者问题。
读者写者问题的定义如下:有一个许多进程共享的数据区,这个数据区可以是一个文件或者主存的一块空间;有一些只读取这个数据区的进程(Reader)和一些只往数据区写数据的进程(Writer),此外还需要满足以下条件:(1)任意多个读进程可以同时读这个文件;(2)一次只有一个写进程可以往文件中写;(3)如果一个写进程正在进行操作,禁止任何读进程度文件。
我们需要分两种情况实现该问题:读优先:要求指一个读者试图进行读操作时,如果这时正有其他读者在进行操作,他可直接开始读操作,而不需要等待。
写优先:一个读者试图进行读操作时,如果有其他写者在等待进行写操作或正在进行写操作,他要等待该写者完成写操作后才开始读操作。
操作系统课程设计--读者-写者问题

操作系统课程设计报告一、操作系统课程设计任务书读者-写者问题实现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()释放指定临界区对象的所有权文件系统的设计通过对文件系统的设计,加深理解文件系统的内部功能及内部实现。
操作系统实验 读者写者问题

《计算机操作系统》实验报告题目读者写者问题学院(部)信息学院专业计算机科学与技术班级学生姓名学号指导教师(签字)一、问题描述一个数据文件或者记录,可以被多个进程共享,我们把只要求读该文件的进程称为“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信号量,以便让其他等待的写者访问共享资源。
除了信号量机制之外,还可以使用其他同步机制来解决读者写者问题,比如互斥量、条件变量等。
同时,操作系统还可以采用优化策略,比如写优先、读写优先等,来提高读写效率。
总之,读者写者问题是操作系统同步问题中的一个经典问题,其实现方式需要考虑多方面的因素,包括并发访问、同步机制、优化策略等,需要经过深入思考和有效实践才能得到较好的解决方案。
读者-写者问题的实现

《操作系统原理》课程设计任务书题目:读者-写者问题的实现学生姓名:学号:班级:_____________题目类型:软件工程(R)指导教师:一、设计目的学生通过该题目的设计过程,掌握读者、写者问题的原理、软件开发方法并提高解决实际问题的能力。
二、设计任务编写程序实现读者优先和写者优先问题:读者-写者问题的读写操作限制(包括读者优先和写者优先)写-写互斥:不能有两个写者同时进行写操作读-写互斥:不能同时有一个线程在读,而另一个线程在写。
读-读允许:可以有一个或多个读者在读。
三、设计要求1.分析设计要求,给出解决方案(要说明设计实现所用的原理、采用的数据结构)。
2.设计合适的测试用例,对得到的运行结果要有分析。
3.设计中遇到的问题,设计的心得体会。
4.文档:课程设计打印文档每个学生一份,并装在统一的资料袋中,资料袋前面要贴有学校统一的资料袋封面。
四、提交的成果1. 课程设计说明书内容包括(1) 封面(学院统一印制);(2) 课程设计任务书;(3) 中文摘要150字;关键词3-5个;(4) 目录;(5) 正文;(设计思想;各模块的伪码算法;函数的调用关系图;测试结果等)(6) 设计总结;(7) 参考文献;(8) 致谢等。
注:每一部分是单独的一章,要另起一页写。
2. 排版要求(1) 所有一级标题为宋体三号加粗(即上面写的2~8部分,单独一行,居中)(2) 所有二级标题为宋体四号加粗(左对齐)(3) 所有三级标题为宋体小四加粗(左对齐)(4) 除标题外所有正文为宋体小四,行间距为固定值22磅,每个段落首行缩进2字符(5) 目录只显示3级标题,目录的最后一项是无序号的“参考文献资料”。
3. 其他要求(班长负责,务必按照以下方式建文件夹)(1) 以班级为单位刻录光盘一张,光盘以班级命名,例如:“10级计算机科学与技术1班”;(2) 光盘内每人一个文件夹,以学号姓名命名——如“10730101 陈映霞”,内容包括任务书、设计文档。
操作系统读者写者问题

操作系统课程设计报告目录目录第1章实验目的和实验要求 (1)1.1 实验目的 (1)1.2 实验要求 (1)1.3 课程设计题目 (1)第2章实验内容 (2)2.1题目分析 (2)2.1.1 问题的描述 (2)2.1.2 问题的解决方法 (2)2.2 算法分析 (3)2.2.1 读者优先算法分析 (3)2.2.2 写者优先算法分析 (8)2.2.3 无优先算法分析 (11)2.3 函数设计 (13)第3章程序实现 (15)3.1 程序功能及界面设计 (15)3.2 实现程序流程 (15)3.2.1 读者优先算法实现 (15)3.2.2 写者优先算法实现 (16)3.2.3 无优先算法实现 (17)3.3 程序流程图 (18)3.3.1 读者优先算法流程图 (18)3.3.2 写者优先算法流程图 (18)3.3.3 无优先算法流程图 (19)心得体会 (21)参考文献 (22)附录1 源代码 (23)第1章实验目的和实验要求第1章实验目的和实验要求1.1 实验目的理解临界区和进程互斥的概念,掌握用信号量和PV操作实现进程互斥的方法。
1.2 实验要求在windows或者linux环境下编写一个控制台应用程序,该程序运行时能创建N个线程,其中既有读者线程又有写者线程,它们按照事先设计好的测试数据进行读写操作。
请用信号量和PV操作实现读者/写者问题。
1.3 课程设计题目本课程设计共包括3个题目,内容覆盖了操作系统原理的关键知识点,包括进程调度、内存管理、进程同步、死锁、进程通讯、文件系统及嵌入式操作系统。
题目1:进程调度算法。
模拟在单处理器情况下的进程调度,目的是加深对进程调度工作的理解,掌握不同调度算法的优缺点题目2:动态异长分区的存储分配与回收算法。
编写一个程序,模拟操作系统对动态异长分区的存储分配与回收算法。
题目3:读者/写者问题与进程同步。
理解临界区和进程互斥的概念,掌握用信号量和PV操作实现进程互斥的方法。
操作系统读者写着问题

课程设计报告课程名称操作系统教程课题名称模拟读者写者问题专业通信工程班级1001班学号201003040111姓名刘新超指导教师田娟秀、颜国风、李杰君2013年7 月5 日湖南工程学院课程设计任务书课程名称操作系统教程课题模拟读者写者问题专业班级通信1001班学生姓名刘新超学号201003040111指导老师田娟秀、颜国风、李杰君审批任务书下达日期2013 年 6 月24 日任务完成日期2013 年7 月 5 日一、设计内容与设计要求1 设计内容:课题5:模拟实现读者写者问题读者写者问题是一个经典的并发程序设计问题,是经常出现的一种同步问题。
所谓读者写者问题,是指保证一个writer进程必须与其他进程互斥地访问共享对象的同步问题。
读者写者问题可以这样的描述,有一群写者和一群读者,写者在写同一本书,读者也在读这本书,多个读者可以同时读这本书,但是,只能有一个写者在写书,并且,读者比写者优先,也就是说,读者和写者同时提出请求时,读者优先。
当读者提出请求时需要有一个互斥操作,另外,需要有一个信号量S来当前是否可操作。
2 选题方案:所选题目根据学号确定,学号模7加1,即(学号%7+1)。
如你的学号为9,则所选题目号为:9%7+1=(题目3)。
3 设计要求:3.1 课程设计报告规范(1)需求分析a.程序的功能。
b.输入输出的要求。
(2)概要设计a.程序由哪些模块组成以及模块之间的层次结构、各模块的调用关系;每个模块的功能。
b.课题涉及的数据结构和数据库结构;即要存储什么数据,这些数据是什么样的结构,它们之间有什么关系等。
(3)详细设计a.采用C语言定义相关的数据类型。
b.写出各模块的类C码算法。
c.画出各函数的调用关系图、主要函数的流程图。
(4)调试分析以及设计体会a.测试数据:准备典型的测试数据和测试方案,包括正确的输入及输出结果和含有错误的输入及输出结果。
b.程序调试中遇到的问题以及解决问题的方法。
c.课程设计过程经验教训、心得体会。
操作系统OS报告读者与写者问题(进程同步问题)

目录一、课程设计目的及要求 (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为等待的对象,也就是实现同步或者互斥的对象。
读者写者问题操作系统课程设计

某某大学课程设计报告课程名称:操作系统课程设计设计题目:读者写者问题系别:计算机系专业:计算机科学与技术组别:第四组学生姓名: 某某某学号:起止日期:指导教师:目录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)。
学号:课程设计课程名称操作系统学院计算机科学与技术学院专业软件工程班级姓名指导教师2014——2015学年第1学期1《操作系统原理》课程设计指导书课程编号:课程名称:操作系统/Operating System周数/学分:1周/1学分先修课程:高级语言程序设计、汇编语言、数据结构、计算机组成原理适用专业:计算机科学与技术、软件工程开课学院、系或教研室:计算机科学与技术学院一、课程设计的目的通过对操作系统内核实现代码的阅读、修改、设计,理解和掌握复杂的操作系统的工作原理。
二、课程设计的内容和要求1.系统调用学习在Linux中产生一个系统调用以及怎样通过往Linux内核中增加一个新函数从而在该内核空间中实现对用户空间的读写。
这个函数的功能是返回当前的系统时间。
实验条件要求:每人一台Linux主机且有超级用户权限。
2.内核定时器通过研究内核的时间管理算法学习内核源代码。
然后应用这些知识并且使用“信号”建立一种用户空间机制来测量一个多线程程序的执行时间。
实验条件要求:每人一台Linux主机且有超级用户权限。
3.实现生产者消费者(Bounded – Buffer Problem)问题通过研究Linux的线程机制和信号量实现生产者消费者(Bounded Buffer)问题的并发控制。
实验条件要求:每人一台与Linux主机联网的Windows主机,普通用户权限。
4.实现读者写者(Reader-Writer Problem)问题通过研究Linux的线程机制和信号量实现读者写者(Reader-Writer)问题并发控制。
实验条件要求:每人一台与Linux主机联网的Windows主机,普通用户权限。
三、课程设计进度安排四、课程设计说明书与图纸要求应包含如下内容:1.设计题目与要求2.总的设计思想及系统平台、语言、工具等。
3.数据结构与模块说明(功能与流程图)4.源程序5.运行结果与运行情况6.调试记录7.自我评析和总结五、课程设计评分标准注:优(90-100分)、良(80-89分)、中(70-79分)、及格(60-69分)、60分以下为不及格。
六、课程设计参考资料推荐教材:《Operating System Concepts(Sixth Edition)(操作系统概念)影印版》,主编:AbrahamSilberschatz出版社:高等教育出版社出版或修订时间:2003年10月参考书:《计算机操作系统教程(第三版)》主编:张尧学出版社:清华大学出版社出版或修订时间:2001年7月《操作系统原理(第三版)》,主编:庞丽萍出版社:华中科技大学出版社出版或修订时间:2000年12月执笔:杨铭熙审阅:陈天煌审定:徐东平课程设计任务书学生姓名:专业班级:软件工程指导教师:刘军工作单位:计算机科学与技术学院题目: 实现读者写者(Reader-Writer Problem)问题实验条件要求:通过研究Linux的线程机制和信号量实现读者写者(Reader-Writer)问题并发控制。
每人一台与Linux主机联网的Windows主机,普通用户权限。
课程设计进度安排2014年 12月 26日目录1 设计目的与要求 (1)1.1 课程设计目的 (1)1.2 课程设计要求 (1)2 总的设计思想及系统平台、语言、工具等 (1)2.1 设计思想 (1)2.2 系统平台及使用语言 (2)2.3 开发工具的选择 (2)3 数据结构和模块说明 (2)3.1 主函数 (2)3.2 写者线程函数 (3)3.3 读者线程函数 (3)4 源程序 (5)5 运行结果与运行情况 (13)6 调试记录 (30)7 自我评析和总结 (31)8 参考文献 (32)2设计目的与要求2.1课程设计目的通过研究Linux的线程机制和信号量实现读者写者(Reader-Writer)问题并发控制。
2.2课程设计要求1.每个读者/写者对该存储区进行操作后,即时显示该存储区的全部内容、当前指针位置和读者/写者线程的标识符;2.读者应有3个以上,写者应有有两个以上;3.多个读者/写者之间须共享对存储区进行操作的函数代码。
3总的设计思想及系统平台、语言、工具等3.1设计思想为实现reader与writer线程间在读或写时的互斥设置一个互斥信号量writer_mutex。
另外,再设置一个整形变量reader_counter表示正在读的线程数目。
由于只有一个reader线程在读,便不允许writer线程去写。
因此,仅当reader_counter=0,表示尚无reader线程在读时,reader线程才需要执行wait(writer_mutex)操作。
若wait(writer_mutex)操作成功,reader线程便可以去读,相应的,做reader_counter+1操作。
同理,仅当reader线程在执行reader_counter 减1操作后其值为0时,才必须执行signal(writer_mutex)操作,以便让writer线程写。
reader_counter是一个可被多个reader线程访问的临界资源,因此,也应该为它设置一个互斥信号量reader_mutex。
3.2系统平台及使用语言本课程设计在Linux操作系统下,使用C语言完成。
用到的工具主要有GCC 编译器和VI编辑器。
3.3开发工具的选择内存:1G工具:g++,vim,geany4数据结构和模块说明4.1主函数图3-1 主函数流程图4.2写者线程函数图3-2写者线程函数流程图4.3读者线程函数图3-3 读者线程函数流程图5源程序/*reader-writer Problemauther : zhengfei rj0315Modole:Shared datasemaphore mutex, wrt;Initiallymutex = 1, wrt = 1, readcount = 0writer process:begindo {wait(wrt);writing;signal(wrt);}while(1);endReader process:begindo {wait(mutex);readcount++;if (readcount == 1)wait(rt);signal(mutex);reading;wait(mutex);readcount--;if (readcount == 0)signal(wrt);signal(mutex);}while(1);end***/#include <iomanip>#include <unistd.h>#include <stdio.h>#include <pthread.h>#include <math.h>#include <time.h>#include <stdlib.h>#include <iostream>#include <fstream>#include <string>#include <semaphore.h>#define readerNum 5#define writerNum 7#define BUFFERSIZE 20using namespace std;int writeRoom[writerNum];//to store which buffer every writer are writing int readRoom[readerNum];//to store which buffer every reader are reading int buffer[BUFFERSIZE];//the bufferstring bufferOwn[BUFFERSIZE];//who use the buffer int readcount=0;int readp=0;int writerp=0;int content_id=0;//the content id of the buffersem_t mutex;sem_t wrt;time_t now;ofstream fout("out.txt");string int2str(int n){char temp[8];sprintf(temp,"%d",n);return (string)temp;}void showbuffer(){int width=4;for(int i=0;i<BUFFERSIZE;i++){bufferOwn[i]="";fout<<setw(width)<<buffer[i];cout<<setw(width)<<buffer[i];}fout<<endl;cout<<endl;for(int i=0;i<readerNum;i++){if(readRoom[i]!=-1)bufferOwn[readRoom[i]]+="r"+int2str(i);}for(int i=0;i<writerNum;i++){if(writeRoom[i]!=-1)bufferOwn[writeRoom[i]]+="w"+int2str(i);}for(int i=0;i<BUFFERSIZE;i++){fout<<setw(width)<<bufferOwn[i];cout<<setw(width)<<bufferOwn[i];}fout<<endl;cout<<endl;}string gettime(){time(&now);string t=ctime(&now);return t;}void writing(int n){writeRoom[n]=rand()%BUFFERSIZE;//set the write place randomlywriterp=writeRoom[n];//the current write placebuffer[writerp]=content_id++;//the writing content ,the content is recognise by a series of id which will increase as 1,2,3,4...fout<<"\nwriter "<<n<<" start to write buffer"<<writerp<<" on "<<gettime();cout<<"\nwriter "<<n<<" start to write buffer"<<writerp<<" on "<<gettime();showbuffer();sleep(rand()%2+1);fout<<"\nwriter "<<n<<" finish writing buffer"<<writerp<<" on "<<gettime();cout<<"\nwriter "<<n<<" finish writing buffer"<<writerp<<" on "<<gettime();writeRoom[n]=-1;showbuffer();}void reading(int n){sem_wait (&mutex);readRoom[n]=rand()%BUFFERSIZE;fout<<"\nreader "<<n<<" start to read buffer"<<readRoom[n]<<" on "<<gettime();cout<<"\nreader "<<n<<" start to read buffer"<<readRoom[n]<<" on "<<gettime();showbuffer();sem_post(&mutex);sleep(rand()%2+1);sem_wait (&mutex);fout<<"\nreader "<<n<<" finish reading buffer"<<readRoom[n]<<" on "<<gettime();cout<<"\nreader "<<n<<" finish reading buffer"<<readRoom[n]<<" on "<<gettime();fout<<"\nthere is "<<readcount-1<<" readers are still reading"<<endl;cout<<"\nthere is "<<readcount-1<<" readers are still reading"<<endl;readRoom[n]=-1;showbuffer();sem_post(&mutex);}void *writer_thread(void * wid){while(1){/*wait(wrt);*/sem_wait(&wrt);/*writing;*/writing((int)wid);/*signal(wrt);*/sem_post(&wrt);/*sleep a while and then write again*/sleep(rand()%5+1);}}void *reader_thread(void *rid){while(1){/*wait(mutex);*/sem_wait(&mutex);readcount++;if (readcount == 1)/*wait(wrt);*/sem_wait(&wrt);/* signal(mutex);*/sem_post(&mutex);/*add emptybottle to buffer;*/reading((int)rid);/*wait(mutex);*/sem_wait(&mutex);readcount--;if (readcount == 0)/*signal(wrt);*/sem_post(&wrt);/*signal(mutex); */sem_post(&mutex);/*sleep a while and then read again*/sleep(rand()%5+1);}}int main(int argc,char *argv[]){/* init */pthread_t reader[readerNum],writer[writerNum] ;sem_init(&wrt,0,1);sem_init(&mutex,0,1);for(int i=0;i<BUFFERSIZE;i++){buffer[i]=-1;bufferOwn[i]="";}for(int i=0;i<readerNum;i++){readRoom[i]=-1;}for(int i=0;i<writerNum;i++){writeRoom[i]=-1;}/*create threads*/for(int i=0;i<readerNum;i++){pthread_create(&reader[i], NULL, reader_thread, (void *)i);}for(int i=0;i<writerNum;i++){pthread_create(&writer[i], NULL, writer_thread, (void *)i);}sleep(40);fout.close();exit(0);return 0;}6运行结果与运行情况在本程序的实现过程中,使用了vim编辑器。