操作系统实验-读者写者问题
- 格式:docx
- 大小:136.26 KB
- 文档页数:8
电子科技大学计算机学院实验中心小心计算机专业类课程实验报告课程名称:操作系统学 院:软件学院专 业:软件工程学生姓名:李 希学 号:2010231020018指导教师:丁老师日 期: 2012年5月5日电子科技大学实验报告实验一一、实验名称:进程管理二、实验学时:4三、实验内容和目的:实验内容:(1)进程的创建写一段源程序,创建两个进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示字符。
观察纪录屏幕上的显示结果,然后分析原因。
(2)进程的控制修改编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕出现的现象,并分析原因。
实验目的:(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)分析进程竞争资源现象,学习解决进程互斥的方法。
四、实验原理:利用fork函数来创建子进程,并返回子进程的ID号。
利用lockf函数来实现信号量对进程的资源竞争的调度,和互斥的方法。
五、实验器材(设备、元器件):一台装有VS2010的电脑,操作系统为WIN7.六、实验步骤:(1)先写好2个子进程程序,并且让2个子程序在屏幕上分别打印出A,B(2)父进程创建2个子进程,并在屏幕上打印出C。
(3)观察进程竞争资源的现象。
七、实验数据及结果分析:电子科技大学计算机学院实验中心子进程A的代码:#include<iostream>#include<windows.h>using namespace std;int main(){cout<<"I'm Process A/n"<<endl;return 0;}子进程B的代码:#include<iostream>using namespace std;int main(){cout<<"I'm Process B"<<endl;;return 0;}父进程C的代码://#include "stdafx.h"#include<windows.h>#include<iostream>using namespace std;void print_error(){DWORD nErrorNo = GetLastError ( );LPSTR lpBuffer;FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS |FORMAT_MESSAGE_FROM_SYSTEM,NULL,nErrorNo,LANG_NEUTRAL,(LPTSTR) & lpBuffer,0 ,NULL );if (lpBuffer == NULL){lpBuffer = "Sorry, cannot find this error info. ";}printf("%s (%d).\n", lpBuffer, nErrorNo);}int fork(const char* pszApplication,HANDLE& hProcess){STARTUPINFO si={sizeof(si)};PROCESS_INFORMATION pi;if(!CreateProcess(pszApplication,NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) return -1;else{hProcess=pi.hProcess;return pi.dwProcessId;}}void lockf(HANDLE hObj){DWORD state = WaitForSingleObject(hObj,INFINITE);switch (state){case WAIT_OBJECT_0:printf("\nProcess exit.\n");break;case WAIT_TIMEOUT:printf("\nTime out.\n");break;case WAIT_FAILED:printf("\nWait Failed.\n");print_error();break;}}int main(int argc, char* argv[]){HANDLE hProcess1,hProcess2;int child1=fork("C:\\操¨´作Á¡Â系¦Ì统ª3实º¦Ì验¨¦\\ProcessA\\Debug\\ProcessA.exe",hProcess1);if(-1==child1){cout << "fork error!\n";return -1;}lockf(hProcess1);电子科技大学计算机学院实验中心int child2=fork("C:\\操¨´作Á¡Â系¦Ì统ª3实º¦Ì验¨¦\\ProcessB\\Debug\\ProcessB.exe",hProcess2);if(-1==child2){cout << "fork error!\n";return -1;}cout<<"This is Process C\n";lockf(hProcess2);return 0;}程序运行的结果:八、实验结论、心得体会和改进建议:实验结论:成功的通过了父进程C来创建了2个子进程A,B,并成功的对子进程进行了调度与管理。
操作系统课程设计课题:读者写者问题姓名:赫前进班级: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 个读者或写者。
每个线程按相应测试数据文件(格式见下)的要求进行读写操作。
操作系统试验--读者-写者问题周俊霞20112113202011211307班进程同步一.实习要求:本课程实验内容引自《Windows 内核实验教程》(陈向群、林斌等编著,机械工业出版社2002.9)。
在Windows 环境下,创建一个包含n 个线程的控制进程。
用这n 个线程来表示n个读者或写者。
每个线程按相应测试数据文件的要求,进行读写操作。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
1.读者-写者问题的读写操作限制:1)写-写互斥;2)读-写互斥;3)读-读允许;2.读者优先的附加限制:如果一个读者申请进行读操作时已有另一读者正在进行读操作,则该读者可直接开始读操作。
写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确信所有处理都遵守相应的读写操作限制。
二.测试数据文件格式测试数据文件包括n 行测试数据,分别描述创建的n 个线程是读者还是写者,以及读写操作的开始时间和持续时间。
每行测试数据包括四个字段,各字段间用空格分隔。
第一字段为一个正整数,表示线程序号。
第一字段表示相应线程角色,R 表示读者是,W 表示写者。
第二字段为一个正数,表示读写操作的开始时间。
线程创建后,延时相应时间(单位为秒)后发出对共享资源的读写申请。
第三字段为一个正数,表示读写操作的持续时间。
当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。
下面是一个测试数据文件的例子:1 R 3 52 W 4 53 R 5 24 R 6 55 W 5.1 3三、与实验相关的API 介绍在本实验中可能涉及的API 有:线程控制:CreateThread 完成线程创建,在调用进程的地址空间上创建一个线程,以执行指定的函数;它的返回值为所创建线程的句柄。
学号:课程设计题目用多线程同步方法解决读者-写者问题(Reader-Writer Problem)学院计算机科学与技术学院专业软件工程班级姓名指导教师2010 年 6 月日目录目录 (1)课程设计任务书 (1)正文 (2)1.设计目的与要求 (2)1.1设计目的 (2)1.2设计要求 (2)2.设计思想及系统平台 (2)2.1设计思想 (2)2.2系统平台及使用语言 (3)3.详细算法描述 (3)4.源程序清单 (6)5.运行结果与运行情况 (9)6.调试过程 (11)7.总结 (12)本科生课程设计成绩评定表 (13)课程设计任务书学生姓名:专业班级:指导教师:工作单位:计算机科学与技术学院题目: 用多线程同步方法解决读者-写者问题(Reader-Writer Problem)初始条件:1.操作系统:Linux2.程序设计语言:C语言3.设有20个连续的存储单元,写入/读出的数据项按增序设定为1-20这20个字符。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.技术要求:1)为每个读者/写者产生一个线程,设计正确的同步算法2)每个读者/写者对该存储区进行操作后,即时显示该存储区的全部内容、当前指针位置和读者/写者线程的自定义标识符。
3)读者应有3个以上,写者应有有两个以上。
4)多个读者/写者之间须共享对存储区进行操作的函数代码。
2.设计说明书内容要求:1)设计题目与要求2)总的设计思想及系统平台、语言、工具等。
3)数据结构与模块说明(功能与流程图)4)给出用户名、源程序名、目标程序名和源程序及其运行结果。
(要注明存储各个程序及其运行结果的主机IP地址和目录。
)5)运行结果与运行情况(提示: (1)连续存储区可用数组实现。
(2)编译命令可用:cc -lpthread -o 目标文件名源文件名(3)多线程编程方法参见附件。
)3. 调试报告:1) 调试记录2)自我评析和总结上机时间安排:18周一~ 五08:0 -12:00指导教师签名:年月日系主任(或责任教师)签名:年月日正文1.设计目的与要求1.1设计目的通过研究Linux的线程机制和信号量实现读者写者问题(Reader-Writer Problem )的并发控制。
操作系统——读者-写者问题的解决⽅法问题描述不允许Write进程和Read进程或其他Write进程同时访问⽂件,Read进程可以和其他Read进程同时访问。
分为三种类型。
读者优先要求:1.多个读者可以同时访问⽂件2.同⼀时间只允许⼀个写者访问⽂件3.读者和写者进程互斥解决⽅法:⽤⼀个readcounter记录是第⼏个读者在读,如果是第⼀个读者,则不能让写者写,需要⼀个锁。
因为readcounter是临界资源,也需要⼀个互斥量。
semaphore rc_mutex = 1, wmutex = 1;readcounter = 0;void writer{do{wait(wmutex);//writesignal(wmutex);}while(TRUE);}void reader{do{wait(rc_mutex);if(readcounter == 0) wait(wmutex);readcounter ++;signal(rc_mutex);// readwait(rc_mutex);readcounter --;if(!readcounter) signal(wmutex);signal(rc_mutex);}while(TRUE);}写者优先要求:1.读者写者互斥2.写者读者同时等待时,所有等待的写者优先,等所有写者结束后,读者才能读3.没有写者时,读者能同时读4.写者到来时,不会终⽌已经进⾏的读者操作解决⽅法:semaphore wc_mutex = 1, prior = 1; //写者计数器,优先信号量readcounter = 0, writercounter = 0;void writer{do{wait(wc_mutex); //申请更改wc的权限if(writercounter == 0) //如果是第⼀个写者,就申请优先权限wait(prior);writercounter ++;signal(wc_mutex);wait(wmutex);//writesignal(wmutex);wait(wc_mutex);writercounter --;if(!writercounter)signal(prior); //当最后⼀个写者操作完成后,释放优先级权限 signal(wc_mutex);}while(TRUE);}void reader{do{wait(prior); //先申请优先级权限,如果前⾯还有写者就等待wait(rc_mutex);if(readcounter == 0) wait(wmutex);readcounter ++;signal(rc_mutex);signal(prior); //释放优先级权限// readwait(rc_mutex);readcounter --;if(!readcounter) signal(wmutex);signal(rc_mutex);}while(TRUE);}读写均等semaphore prior = 1; //读者和写者都等待在⼀个队列上,实现读写均等readcounter = 0, writercounter = 0;void writer{do{wait(prior);wait(wmutex);//writesignal(wmutex);signal(prior);}while(TRUE);}void reader{do{wait(prior);wait(rc_mutex);if(readcounter == 0) wait(wmutex);readcounter ++;signal(rc_mutex);signal(prior);//readwait(rc_mutex);readcounter --;if(!readcounter) signal(wmutex);signal(rc_mutex);}while(TRUE);}有错误请指出!。
读者写者问题实验报告1. 引言读者写者问题是操作系统中的经典同步问题,用于研究多线程环境下对共享资源的访问和保护。
在该问题中,有多个读者和写者同时对一个共享资源进行操作,需要保证并发访问时的正确性和效率。
通过本实验,我们将探讨读者写者问题的解决方案,并比较不同算法的性能差异。
2. 实验目标本实验的主要目标是通过实现和比较不同的读者写者问题算法,深入了解并发访问的挑战和解决方案。
具体而言,我们将研究以下几个方面:•设计并实现读者写者问题的解决方案•比较不同算法的性能差异•分析可能的优化策略3. 实验方法我们将使用Python编程语言来实现读者写者问题的解决方案。
在实验过程中,我们将尝试以下几种常见的算法:3.1. 读者优先算法在读者优先算法中,当有读者在访问共享资源时,其他读者可以同时访问,但写者需要等待。
只有当所有读者完成访问后,写者才能获得访问权限。
3.2. 写者优先算法在写者优先算法中,当有写者在访问共享资源时,其他读者和写者都需要等待。
只有当写者完成访问后,其他读者或写者才能获得访问权限。
3.3. 公平算法在公平算法中,读者和写者的访问权限是公平的,先到先得。
无论读者还是写者,都需要按照到达的顺序依次获取访问权限。
4. 实验步骤下面是我们实施实验的具体步骤:4.1. 实现基本的读者写者问题解决方案我们首先实现基本的读者写者问题解决方案,包括读者和写者的线程逻辑和共享资源的访问控制。
我们将使用互斥锁和条件变量来保证并发访问的正确性。
4.2. 实现读者优先算法在已有的基本解决方案的基础上,我们实现读者优先算法。
我们将通过优化访问控制的逻辑来实现读者优先的特性。
4.3. 实现写者优先算法类似地,我们在基本解决方案的基础上实现写者优先算法。
我们将调整访问控制的逻辑,使得写者优先于其他读者和写者。
4.4. 实现公平算法最后,我们实现公平算法。
我们将结合队列和条件变量等技术来确保读者和写者的访问顺序是公平的。
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)读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。
操作系统读者-写者问题模拟读者-写者问题模拟目录操作系统读者-写者问题模拟----------------------------------------------------------------------------- - 1 -一、设计概述 ------------------------------------------------------------------------------------------------------- - 2 -二、设计目的与内容 ---------------------------------------------------------------------------------------------- - 3 -一、实验目的--------------------------------------------------------------------------------------------------- - 3 -二、实验内容--------------------------------------------------------------------------------------------------- - 3 -三、设计分析--------------------------------------------------------------------------------------------------- - 3 -四. 程序实现 --------------------------------------------------------------------------------------------------------- - 4 -五、程序调试 --------------------------------------------------------------------------------------------------------- - 4 -六、结果分析和讨论------------------------------------------------------------------------------------------------ - 4 -七、源程序 ------------------------------------------------------------------------------------------------------------ - 5 -一、设计概述所谓读者写者问题,是指保证一个writer进程必须与其它进程互斥地访问共享对象的同步问题。
实验3 读者/写者问题与进程同步3.1 实验目的理解临界区和进程互斥的概念,掌握用信号量和PV操作实现进程互斥的方法。
3.2 实验要求在windows或者linux环境下编写一个控制台应用程序,该程序运行时能创建N个线程,其中既有读者线程又有写者线程,它们按照事先设计好的测试数据进行读写操作。
请用信号量和PV操作实现读者/写者问题。
读者/写者问题的描述如下:有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间,甚至可以是一组处理器寄存器。
有一些只读取这个数据区的进程(reader)和一些只往数据区中写数据的进程(writer)。
以下假设共享数据区是文件。
这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。
这些条件具体来说就是:(1)任意多的读进程可以同时读这个文件;(2)一次只允许一个写进程往文件中写;(3)如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;(4)写进程执行写操作前,应让已有的写者或读者全部退出。
这说明当有读者在读文件时不允许写者写文件。
对于读者-写者问题,有三种解决方法:1、读者优先除了上述四个规则外,还增加读者优先的规定,当有读者在读文件时,对随后到达的读者和写者,要首先满足读者,阻塞写者。
这说明只要有一个读者活跃,那么随后而来的读者都将被允许访问文件,从而导致写者长时间等待,甚至有可能出现写者被饿死的情况。
2、写者优先除了上述四个规则外,还增加写者优先的规定,即当有读者和写者同时等待时,首先满足写者。
当一个写者声明想写文件时,不允许新的读者再访问文件。
3、无优先除了上述四个规则外,不再规定读写的优先权,谁先等待谁就先使用文件。
3.3实验步骤3.3.1 算法分析有同学认为,可以将文件视为临界资源,使用临界资源的代码就构成临界区,为了对临界区进行管理,只需设置一个互斥信号量r_w_w,读或者写之前执行P(r_w_w),之后执行V(r_w_w)即可,从而得到图3-1所示的算法描述。
操作系统读者写者实验报告一、实验目的通过实验理解读者写者问题的实现原理,掌握相关的同步机制,实现读者写者问题的经典解法,并对比不同解法的优缺点。
二、实验原理1.读者写者问题读者写者问题是指在多个线程同时读写一个共享数据的情况下可能出现的问题。
其问题的核心在于多个读线程可以同时读,但只能有一个写线程能够写,并且在写操作过程中不能有任何的读操作。
2.互斥与同步为了解决读者写者问题,在多线程并发读写共享数据时,需要使用互斥与同步机制来保证数据的完整性和一致性。
-互斥:通过锁机制来保证只允许一个线程进入临界区,其他线程需要等待锁的释放。
-同步:通过信号量等机制来保证线程按照一定顺序执行。
三、实验步骤本次实验中将实现两个版本的读者写者问题解决方案:一是使用互斥锁和条件变量,二是使用信号量。
1.使用互斥锁和条件变量(1)定义全局变量和互斥锁:共享数据、读者数目、互斥锁、写者条件变量、读者条件变量。
(2)初始化互斥锁和条件变量。
(3)写者线程的实现:获取互斥锁,判断当前是否有读者或写者,如果有则等待条件变量,然后进行写操作,释放互斥锁。
(4)读者线程的实现:获取互斥锁,判断是否有写者,如果有则等待条件变量,否则增加读者数目并释放互斥锁,进行读操作。
(5)测试程序的运行并输出结果。
2.使用信号量(1)定义全局变量和信号量:共享数据、读者信号量、写者信号量、用于保护读者数目和写者数目的互斥信号量。
(2)初始化信号量和互斥信号量。
(3)写者线程的实现:首先获取写者互斥信号量,然后获取写者信号量,进行写操作,释放写者信号量和写者互斥信号量。
(4)读者线程的实现:首先获取读者互斥信号量,然后增加读者数目,如果是第一个读者则获取写者信号量,然后进行读操作,释放读者信号量和读者互斥信号量,如果是最后一个读者则释放写者信号量。
(5)测试程序的运行并输出结果。
四、实验结果与分析通过对比两种解决方案,可以得出以下结论:1.使用互斥锁和条件变量的解决方案相对较为简单,但可能存在饥饿问题,即可能会导致一些线程一直无法访问共享资源。
实验3 经典同步互斥问题1.实验目的·通过编写程序熟悉并发,同步/互斥,死锁等概念2.实验内容[基本要求]编写Linux环境下C程序,实现3个经典的同步/互斥问题[具体要求]·生产者/消费者问题设计思路:1)首先建立缓冲池,循环队列#define BUFFSIZE 9 // 缓冲池大小struct queue_type //缓冲池队列{int buff[BUFFSIZE];int front; //队头,消费者从对头取出"产品”int rear; //队尾,生产者从队尾放入"产品“}Q={{0},0,0};2)设置信号量实现互斥sem_t pro_empty; // 生产者私有信号量,表示空缓冲区数目。
sem_t con_full; //消费者私有变量,表示有产品的缓冲区数目。
sem_t mutex; //实现对临界区互斥访问的信号量3)设计生产者函数生产者必须首先申请空缓冲区,缓冲区有空闲才能生产sem_wait(&pro_empty);然后进入缓冲区生产,进入之前利用mutex互斥sem_wait(&mutex); //信号量申请缓冲区互斥Q.buff[Q.rear] = 1; //将产品放入rear所指向的缓冲区print();Q.rear = (Q.rear+1) % BUFFSIZE;//注意要模,因为是循环队列sem_post(&mutex); //释放互斥sem_post(&con_full);//释放满缓冲区4)设计消费者函数消费者必须首先申请满缓冲区,缓冲区有东西才能消费sem_wait(&con_full);然后进入缓冲区消费,进入之前利用mutex互斥sem_wait(&mutex);Q.buff[Q.front] = 0; //从front所指向的缓冲区取产品print();Q.front = (Q.front+1) % BUFFSIZE;sem_post(&mutex);//释放队列互斥sem_post(&pro_empty);// //释放空缓冲区·读者问题设计思路:1)设置互斥锁pthread_mutex_t writer_lock = PTHREAD_MUTEX_INITIALIZER;//同一时间只能一个人写文件,互斥pthread_mutex_t access_readercount = PTHREAD_MUTEX_INITIALIZER;//同一时间只能有一个人访问readerCnt2)设计写者函数进入临界区写,进入之前利用互斥锁互斥pthread_mutex_lock(&writer_lock);write();pthread_mutex_unlock(&writer_lock);3)设计读者优先函数如果有一个读者在读,则后面的读者来到都可以读,所以要把所有写者锁上pthread_mutex_lock(&access_readercount);//临界区互斥readercount++;if(readercount == 1){pthread_mutex_lock(&writer_lock);//把读者锁上}pthread_mutex_unlock(&access_readercount);读数据,读之前利用互斥锁互斥pthread_mutex_unlock(&access_readercount);read();pthread_mutex_lock(&access_readercount);如果最后一个读者退出,则要把原来锁上写者的锁打开pthread_mutex_lock(&access_readercount);readercount--;if(readercount == 0){pthread_mutex_unlock(&writer_lock);}pthread_mutex_unlock(&access_readercount);·写者问题设计思路:1)设置互斥锁//实现读者读时互斥pthread_mutex_t access_readercount = PTHREAD_MUTEX_INITIALIZER;//实现写者写时互斥pthread_mutex_t access_writercount = PTHREAD_MUTEX_INITIALIZER;//实现把写者锁上pthread_mutex_t writer_lock = PTHREAD_MUTEX_INITIALIZER;//实现把一个读者锁上pthread_mutex_t reader_lock = PTHREAD_MUTEX_INITIALIZER;//实现把成千上万读者锁上pthread_mutex_t outer_lock = PTHREAD_MUTEX_INITIALIZER;2)设计写者优先函数如果第一个写者来了,那么禁止所有读者pthread_mutex_lock(&access_writercount);{//临界区,希望修改writercount,独占writercountwritercount++;//写者数量加1if(writercount == 1){//后续的读者加入待读队列pthread_mutex_lock(&reader_lock);}}pthread_mutex_unlock(&access_writercount);写数据,写之前互斥pthread_mutex_lock(&writer_lock);{//临界区,限制只有一个写者修改数据write();}pthread_mutex_unlock(&writer_lock);最后一个写者走了,则释放之前所有被禁止的读者pthread_mutex_lock(&access_writercount);{//临界区,希望修改writercount,独占writercountwritercount--;//写者数量减1if(writercount == 0){//释放待读序列中的读者pthread_mutex_unlock(&reader_lock);}}pthread_mutex_unlock(&access_writercount);3)·哲学家问题只有当哲学家的左右两只筷子均可以用的时候,才允许其拿起筷子进餐,否则该哲学家一直请求左边的筷子,若为非阻塞状态(左边的筷子信号量为1则直接占有,信号量为0则进入阻塞状态),则拿起,然后测试右手筷子是什么状态,右边的筷子若信号量为0,则阻塞,进入等待,非阻塞,则吃设计思路:1)设置左右手筷子int right = (id + 1) % PHILO_NUM;int left = id;2)思考状态,然后此哲学家先处于睡眠,然后状态变为饥饿case THINKING:usleep(300);state = HUNGRY;strcpy(ptrState,"thinking");break;3)饥饿状态,则去拿筷子case HUNGRY:if(sem_wait(&chopsticks[left]) == 0){//左筷子非阻塞状态if(sem_trywait(&chopsticks[right]) == 0){//测试右筷子,若为非阻塞,则拿起strcpy(ptrState,"eating ");state = EATING;//状态变为吃}else{state = THINKING;//拿不到筷子,变为思考状态sem_post(&chopsticks[left]);//释放已经请求的得到的左筷子}}break;4)吃状态,释放左右手筷子,之后状态变为思考sem_post(&chopsticks[left]);sem_post(&chopsticks[right]);usleep(500);state = THINKING;strcpy(ptrState,"thinking");break;·代码有注释,提交实验报告和源代码[进一步要求]·多个生产者和消费者在主函数中可以输入你想设置的生产者和消费者数目printf("please input the producers number: ");scanf("%d",&M);printf("please input the consumers number: ");scanf("%d",&N);·多个读者和写者,考虑读者优先或是写者优先宏定义读者写者数目#define N_WRITER 3 //写者数目#define N_READER 5 //读者数目·用区别于示例代码的思想实现哲学家问题利用了sem_trywait()函数·可视化展示输出结果。
实验3 读者/写者问题与进程同步3.1 实验目的理解临界区和进程互斥的概念,掌握用信号量和PV操作实现进程互斥的方法。
3.2 实验要求在linux环境下编写一个控制台应用程序,该程序运行时能创建N个线程〔或者进程〕,其中既有读者线程又有写者线程,它们按照事先设计好的测试数据进行读写操作。
请用信号量和PV操作实现读者/写者问题。
读者/写者问题的描述如下:有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间〔比方一个数组或一个变量〕,甚至可以是一组处理器寄存器。
有一些只读取这个数据区的进程〔reader〕和一些只往数据区中写数据的进程〔writer〕。
以下假设共享数据区是文件。
这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。
这些条件具体来说就是:〔1〕任意多的读进程可以同时读这个文件;〔2〕一次只允许一个写进程往文件中写;〔3〕如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;〔4〕写进程执行写操作前,应让已有的写者或读者全部退出。
这说明当有读者在读文件时不允许写者写文件。
对于读者-写者问题,有三种解决方法:1、读者优先除了上述四个规则外,还增加读者优先的规定,当有读者在读文件时,对随后到达的读者和写者,要首先满足读者,阻塞写者。
这说明只要有一个读者活跃,那么随后而来的读者都将被允许访问文件,从而导致写者长时间等待,甚至有可能出现写者被饿死的情况。
2、写者优先除了上述四个规则外,还增加写者优先的规定,即当有读者和写者同时等待时,首先满足写者。
当一个写者声明想写文件时,不允许新的读者再访问文件。
3、无优先除了上述四个规则外,不再规定读写的优先权,谁先等待谁就先使用文件。
实验步骤算法分析有同学认为,可以将文件视为临界资源,使用临界资源的代码就构成临界区,为了对临界区进行管理,只需设置一个互斥信号量r_w_w,读或者写之前执行P(r_w_w),之后执行V(r_w_w)即可,从而得到图3-1所示的算法描述。
读者写者问题实验报告1.实验目的:掌握读者写者问题的基本概念和操作实现方法。
2.实验原理:(1)读者写者问题:1.读者优先:若读者进程正在读文件,写者进程需等待。
2.写者优先:若写者进程正在写文件,读者进程需等待。
3.公平竞争:读写者进程均有机会访问文件。
(2)进程同步:1.信号量:能够同步进程的执行,性能较好。
2.互斥量:能够同步进程的执行,提供了更细粒度的控制。
3.条件变量:让进程能够进行相互之间的协作。
3.实验内容:(1)依照读者写者问题的操作实现方法,采用信号量机制,编写读者进程和写者进程。
(2)测试不同读者写者优先级下程序的执行情况。
4.实验步骤:(1)设计程序架构:1.使用信号量实现读者写者访问文件的同步操作;2.设计Readers和Writers两个类分别实现读者和写者进程的操作。
(2)实现程序:1.编写读者进程,在进程对文件进行读操作之前使用信号量P操作,读取完成后使用信号量V操作;2.编写写者进程,在进程对文件进行写操作之前使用信号量P操作,写入完成后使用信号量V操作;3.设计信号量的初始值,以实现不同读者写者优先级下程序的执行情况。
(3)测试程序:在有多个读者进程和多个写者进程的情况下,测试不同读者写者优先级下程序的执行情况。
5.实验结果:(1)读者优先:读者优先的情况下,不管读者进程和写者进程的数量如何设置,读者总是有后进先出的机会访问文件。
(2)写者优先:写者优先的情况下,不管读者进程和写者进程的数量如何设置,写者总是有先进先出的机会访问文件。
(3)公平竞争:公平竞争的情况下,读者或写者进程均有机会访问文件。
6.实验结论:(1)在实现读者写者问题的过程中,需要采用进程同步技术来确保进程之间的正确协作。
(2)信号量提供了一种较为有效的进程同步机制,能够满足读者写者问题的操作需求。
(3)采用不同的优先级设置,可以使读者写者进程之间实现不同的访问策略,进而实现不同的访问效果。
一、阅读者写入者问题描述有一个公用的数据集,有很多人需要访问,其中一些需要阅读其中的信息,一些需要修改其中的消息。
阅读者可以同时访问数据集,而写入者只能互斥的访问数据集,不能与任何的进程一起访问数据区。
二、程序运行说明1.本程序主要用于说明阅读者写入者问题中的资源互斥访问的调动策略,并模仿其访问的过程。
采用书上的伪码编制而成,实际上采用的是读优先策略。
2.在本程序中用于表现的图形界面说明:在程序编译运行后会出现中间一个大的圆圈表示公用的资源,上面一排五个矩形表示5个读者,下面的五个矩形表示五个写入者。
每个读者和写入者都有3种状态,休息,等待和操作(读入或者写入)分别用黑颜色,绿颜色,红颜色表示休息,等待和操作。
一旦操作者获得资源,可以进行读或者写,我们就划一条从操作者中心到资源中心的线,表示开始操作。
三、关于阅读者写入者问题的mfc程序分析:A. ReaderAndWriter.c函数说明:B.Mutex.c函数说明:1. DWORD WINAPI ReaderThread (LPVOID pVoid)读者进程:根据前面的资源分配策略,对于读进程,我们初始化设置都是处于休息状态,然后要是资源可读,根据进程到来的快慢,分配资源给读者,是其从休息,等待到读状态,最后释放资源进入休息状态,一直循环。
一旦有一个读者进入临界区,我们就封锁临界区,可以让所用的读者进入,而不让写入者进入,并用一个资源控制readercount,保证每次只有一个进程对变量进行操作。
这样,直到每一个读者都读完,没有一个读者的时候,开始释放临界区,这样写入者就可以进入与读者进行资源的争夺,决定是读还是写。
2. DWORD WINAPI WriterThread (LPVOID pVoid)写入者进程:与读者进程类似,从休息代等待,最后写入,一直循环。
其中只要一个写进程进入临界区,其他的进程就不能进入临界区了,直到写进程释放临界区。
操作系统——读者写者问题⼀、问题描述要求:1、允许多个读者可以同时对⽂件执⾏读操作。
2、只允许⼀个写者往⽂件中写信息。
3、任⼀写者在完成写操作之前不允许其他读者或写者⼯作。
4、写者执⾏写操作前,应让已有的读者和写者全部退出。
⼆、问题分析读者写者问题最核⼼的问题是如何处理多个读者可以同时对⽂件的读操作。
三、如何实现semaphore rw = 1; //实现对⽂件的互斥访问int count = 0;semaphore mutex = 1;//实现对count变量的互斥访问int i = 0;writer(){while(1){P(rw); //写之前“加锁”写⽂件V(rw); //写之后“解锁”}}reader (){while(1){P(mutex); //各读进程互斥访问countif(count==0) //第⼀个读进程负责“加锁”{P(rw);}count++; //访问⽂件的进程数+1V(mutex);读⽂件P(mutex); //各读进程互斥访问countcount--; //访问⽂件的进程数-1if(count==0) //最后⼀个读进程负责“解锁”{V(rw);}V(mutex);}}只要有源源不断的读进程存在,写进程就要⼀直阻塞等待,可能会造成“饿死”,在上述的算法中,读进程是优先的,那么应该怎么样来改造呢?新加⼊⼀个锁变量w,⽤于实现“写优先”!这⾥我们来分析⼀下读者1->写者1->读者2这种情况。
第⼀个读者1在进⾏到读⽂件操作的时候,有⼀个写者1操作,由于第⼀个读者1执⾏了V(w),所以写者1不会阻塞在P(w),但由于第⼀个读者1执⾏了P(rw)但没有执⾏V(rw),写者1将会被阻塞在P(rw)上,这时候再有⼀个读者2,由于前⾯的写者1进程执⾏了P(w)但没有执⾏V(w),所以读者2将会被阻塞在P(w)上,这样写者1和读者2都将阻塞,只有当读者1结束时执⾏V(rw),此时写者1才能够继续执⾏直到执⾏V(w),读者2也将能够执⾏下去。
实验3--读者-写者问题与进程同步实验3 读者/写者问题与进程同步3.1 实验目的理解临界区和进程互斥的概念,掌握用信号量和PV操作实现进程互斥的方法。
3.2 实验要求在linux环境下编写一个控制台应用程序,该程序运行时能创建N个线程(或者进程),其中既有读者线程又有写者线程,它们按照事先设计好的测试数据进行读写操作。
请用信号量和PV操作实现读者/写者问题。
读者/写者问题的描述如下:有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间(比如一个数组或一个变量),甚至可以是一组处理器寄存器。
有一些只读取这个数据区的进程(reader)和一些只往数据区中写数据的进程(writer)。
以下假设共享数据区是文件。
这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。
这些条件具体来说就是:(1)任意多的读进程可以同时读这个文件;(2)一次只允许一个写进程往文件中写;(3)如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;(4)写进程执行写操作前,应让已有的写者或读者全部退出。
这说明当有读者在读文件时不允许写者写文件。
对于读者-写者问题,有三种解决方法:1、读者优先除了上述四个规则外,还增加读者优先的规定,当有读者在读文件时,对随后到达的读者和写者,要首先满足读者,阻塞写者。
这说明只要有一个读者活跃,那么随后而来的读者都将被允许访问文件,从而导致写者长时间等待,甚至有可能出现写者被饿死的情况。
2、写者优先除了上述四个规则外,还增加写者优先的规定,即当有读者和写者同时等待时,首先满足写者。
当一个写者声明想写文件时,不允许新的读者再访问文件。
3、无优先除了上述四个规则外,不再规定读写的优先权,谁先等待谁就先使用文件。
3.3 实验步骤3.3.1 算法分析1、错误的解法 有同学认为,可以将文件视为临界资源,使用临界资源的代码就构成临界区,为了对临界区进行管理,只需设置一个互斥信号量r_w_w ,读或者写之前执行P(r_w_w),之后执行V(r_w_w)即可,从而得到图3-1所示的算法描述。
《计算机操作系统》实验报告题目读者写者问题学院(部)信息学院专业计算机科学与技术班级、学生姓名学号指导教师(签字)一、《二、问题描述一个数据文件或者记录,可以被多个进程共享,我们把只要求读该文件的进程称为“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<>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<>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、执行结果读者优先在读者优先中先两个读者申请,再一个写者申请,再有两个读者申请。
当读者和写者发生申请冲突时,读者优先进入读取。
写者优先在写者优先中,先进入两个读者申请,再一个写者申请,最后两个读者申请。
写者和最后两个读者发生申请冲突时,优先让写者先进入,进行写操作。