操作系统OS报告读者与写者问题(进程同步问题)
读者-写者问题(Reader-Writer Problem)
![读者-写者问题(Reader-Writer Problem)](https://img.taocdn.com/s3/m/ac9b71d7524de518964b7d73.png)
学号:课程设计题目用多线程同步方法解决读者-写者问题(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 )的并发控制。
第10课进程间的制约关系(经典同步问题)
![第10课进程间的制约关系(经典同步问题)](https://img.taocdn.com/s3/m/a14d0fd0ce2f0066f5332252.png)
顾客程序 customer() { V(custs); //释放顾客 P(barbs); //申请理发师 get_haircut(); }
“理发店”问题---P、V信号量解法
设置同步信号量
custs:记录等待理发的顾客数(不包括正在理
发的顾客),初值为0; barbs:正在等待为顾客理发的理发师数,初值 为k;
为防止死锁发生可采取的措施:
最多允许4个哲学家同时坐在桌子周围 仅当一个哲学家左右两边的筷子都可用时, 才允许他拿筷子 给所有哲学家编号,奇数号的哲学家必须首 先拿左边的筷子,偶数号的哲学家则反之
哲学家就餐问题—解法2
0
设置5个互斥信号量: chopstick[i] (0≤i≤4) //对应筷子 初值=1 设置信号量seat // 代表了座位数 初始值=4;
设置变量waiting,它的初值为0。
记录等待理发的顾客数
“理发店”问题---P、V信号量解法
理发师程序 barber() { P(custs); cut_hair(); V(barbs); }
顾客程序 customer() { if(waiting<n) { waiting=waiting+1; V(custs); P(barbs); get_haircut(); } }
第i个哲学家的“思考-就餐-思考”过程可描述为:
philosopher(i) { while(TRUE) { think(); P(chopstick[i]); P(chopstick[(i+1) mod 5)]; eat(); V(chopstick[i]); V(chopstick[(i+1) mod 5)]; } }
OS课程设计__读者写者
![OS课程设计__读者写者](https://img.taocdn.com/s3/m/fcb0842e7fd5360cba1adb74.png)
兰州交通大学操作系统课程设计课程:计算机操作系统题目:进程同步(读者--写者)班级:姓名:学号:指导教师:日期: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设计功能利用模拟用信号量机制实现读者和写者问题:通过用户控制读进程和写进程,反应读者和写者问题中所涉及的进程的同步与互斥。
进程同步模拟设计——读者和写者问题
![进程同步模拟设计——读者和写者问题](https://img.taocdn.com/s3/m/d68257567cd184254b3535e8.png)
学号:课程设计题目进程同步模拟设计——读者和写者问题学院计算机科学与技术学院专业、班级、姓名、指导教师吴利军2013 年01 月17 日课程设计任务书学生:指导教师:吴利军工作单位:计算机科学与技术学院题目: 进程同步模拟设计——读者和写者问题初始条件:1.预备容:阅读操作系统的进程管理章节容,对进程的同步和互斥,以及信号量机制度有深入的理解。
2.实践准备:掌握一种计算机高级语言的使用。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.模拟用信号量机制实现读者和写者问题。
2.设计报告容应说明:⑴需求分析;⑵功能设计(数据结构及模块说明);⑶开发平台及源程序的主要部分;⑷测试用例,运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他方法(如果有,简要说明该方法);时间安排:设计安排一周:周1、周2:完成程序分析及设计。
周2、周3:完成程序调试及测试。
周4、周5:验收、撰写课程设计报告。
(注意事项:严禁抄袭,一旦发现,一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日1 需求分析所谓读者写者问题,是指保证一个 writer 进程必须与其他进程互斥地访问共享资源的同步问题.读者写者问题可以这样的描述,有一群写者和一群读者, 写者在写同一本书,读者也在读这本书,多个读者可以同时读这本书,但是只能有一个写者在写书,并且读者优先,也就是说,读者和写者同时提出请求时,读者优先.当读者提出请求时需要有一个互斥操作, 另外需要有一个信号量 mutex来当前是否可操作.信号量机制是支持多道程序的并发操作系统设计中解决资源共享时进程间的同步与互斥的重要机制,而读者写者问题则是这一机制的一个经典例. 与记录型信号量解决读者—写者问题不同,信号量机制它增加了一个限制,即最多允许n个读者同时读.为此引入了一个信号量Rcount,并赋予初值为 0,通过执行Rcount++操作,来控制读者的数目,每当有一个读者进入时,就要执行Rcount++操作,使 Rcount 的值加1.读者离开时Rcount--;当且仅当Rcount==0时,V (Wmutex),才能进行写操作。
“读写平等”策略的“读者--写者”问题实验报告
![“读写平等”策略的“读者--写者”问题实验报告](https://img.taocdn.com/s3/m/f356fc2be2bd960590c677c4.png)
淮北师范大学程序设计课程设计采用“读写平等”策略的“读者--写者”问题学院计算机科学与技术专业计算机科学与技术(师范)学号 ***********学生姓名 ***指导教师姓名 ***2012年6月16 日一、设计目的与内容课程设计的目的:操作系统课程设计是计算机专业重要的教学环节,它为学生提供了一个既动手又动脑,将课本上的理论知识和实际有机的结合起来,独立分析和解决问题的机会。
●进一步巩固和复习操作系统的基础知识。
●培养学生结构化程序、模块化程序设计的方法和能力。
●提高学生调试程序的技巧和软件设计的能力。
●提高学生分析问题、解决问题以及综合利用C语言进行程序设计的能力。
设计内容:用高级语言编写和调试一个采用“读写平等”策略的“读者—写者”问题的模拟程序。
设计的要求:1.读者与写者至少包括ID、进入内存时间、读写时间三项内容,可在界面上进行输入。
2.读者与写者均有两个以上,可在程序运行期间进行动态增加读者与写者。
3.可读取样例数据(要求存放在外部文件中),进行读者/写者、进入内存时间、读写时间的初始化。
4.要求将运行过程用可视化界面动态显示,可随时暂停,查看阅览室中读者/写者数目、读者等待队列、读写时间、等待时间。
5.读写策略:读写互斥、写写互斥、读写平等(严格按照读者与写者到达的顺序进入阅览室,有写着到达,则阻塞后续到达的读者;有读者到达,则阻塞后续到达的写者)。
有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间,甚至可以是一组处理器寄存器。
有一些只读取这个数据区的进程(reader)和一些只往数据区中写数据的进程(writer)。
以下假设共享数据区是文件。
这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。
这些条件具体来说就是:(1)任意多的读进程可以同时读这个文件;(2)一次只允许一个写进程往文件中写;(3)如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;(4)写进程执行写操作前,应让已有的写者或读者全部退出。
读者-写者问题解答
![读者-写者问题解答](https://img.taocdn.com/s3/m/67626efafab069dc50220109.png)
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)读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。
“读者-写者”算法的讨论和改进
![“读者-写者”算法的讨论和改进](https://img.taocdn.com/s3/m/671639d3ec3a87c24028c477.png)
“读者-写者”算法的讨论和改进作者:宋锦华李伟来源:《中小企业管理与科技·上旬刊》2011年第05期摘要:读者与写者问题是操作系统中的经典进程同步问题之一,文章利用操作系统中的信号量及信号量上的P、V操作,按照教学的方法和思路对传统的读者-写者算法进行了探讨,并将算法加以改进,实现了写者优先功能,同时保证多个并发进程在执行过程中的正确性。
关键词:读者与写者操作系统信号量1 相关概念1.1 利用信号量解决进程间的制约关系多道程序设计环境下,系统中同时执行多个作业进程,这些进程同时共享和竞争系统中的资源,因此必然存在一定的制约关系。
进程间的这些制约关系可分为互斥与同步两种。
互斥即:一个进程对系统中的共享变量或临界资源进行操作时,为了保证它和系统中其它进程的正确执行,不允许其它进程同时对这些共享变量和临界资源进行操作。
同步指:一个进程运行到了某一点时,需要等待其它进程完成某种操作或发来信息,才能继续运行。
那么,如何来控制进程间的互斥和同步,使它们正确运行呢?利用信号量以及信号量上的P、V操作能够很好的解决进程间的互斥与同步关系,从而保证进程的正确执行。
对于互斥来说,假定设置信号量为S,那么,将S的初值设为1,在临界区之前安排P(S)操作,临界区之后安排V(S)操作即可。
对于同步来说,信号量S的初值设为0,在请求同步点安排P(S)操作,在准备同步条件点安排V(S)操作即可。
本文讨论的是操作系统中很经典的进程同步问题之一——读者写者问题。
1.2 传统的读者写者问题一批数据被多个并发进程共享使用。
其中一些进程只要求读数据,因此称为“读者”,一些进程会对数据进行修改,称为“写者”。
多个读者共同工作时,访问不会有问题,但是读者和写者共同访问或者写者和写者共同修改数据时,就有可能会出错,导致错误的访问结果。
因此,关于读者和写者的读写限制,可以分为这样三条:①写-写互斥,即不能有两个写者同时对数据进行写操作。
“读者-写者”算法的讨论和改进
![“读者-写者”算法的讨论和改进](https://img.taocdn.com/s3/m/2cfb68cf89eb172ded63b7df.png)
I ADE 0 THE V W Rr F RE R= N ( - ) 写者 :
PW R ) ( T
修 改 信 息
V( R ) W T
11 利 用 信 号 量 解 决进 程 间 的制 约 关 系 . 多 道程 序 设 计 环 境 下 , 统 中 同 时执 行 多个 作 业 进 程 , 些 进 程 系 这 同时 共 享和 竞争 系统 中的 资 源 , 因此 必 然存 在 一 定 的制 约 关 系 。 程 进
修 改 信 息
V( R ) W T
3 读 者 一 者 算 法 的 改 进— — 写 者 优 先 写
在 算 法 中 , 一 种 极 端 情 况 , 有 一 个 读 者 进 程 在 读 , 使 写 者 有 即 而 读 一 写 互 斥 , 有 读 者 在 对数 据 进 行 访 问 时 , 何 写 者 不 能 对 其 操 进程 被 阻 塞 时 , 仍 然 有 读 者 不 断地 请 求 读 , 么 写 者 有 可 能 因读 者 即 任 却 那
这样 的解 法 看 起来 已经 没 有 问题 了, 因 为 它做 到 了第 一个 读 者
进去 了 , 其他 读 者 也 能 进 , 写者 不 能 进 。 是 又 出 现 了新 的 问 题 , 而 但 那
就是 如 果 是 写 者 先 进去 了 ,第 一 个 读 者 不 能进 ,而 其他 读 者 却 能 进
对这 些 数据 进行 访 问。
2 读 者一 写者 算 法 讨 论
当现 有读 者 完 成 之 后 ,就 让 写者 优 先 运 行 。 为 此添 加 一 个整 型 变 量 W RT C N , 录 写者 的数 目, W RT C IE OU T记 当 IE OU T = N 0时 才 可 以释 为 了实现 对 全局 变 量 W RT C N IE OU T的 互 斥访 问, 设置 了一个 互
操作系统之读者与写者问题(C++)
![操作系统之读者与写者问题(C++)](https://img.taocdn.com/s3/m/e8ecb4de79563c1ec4da712e.png)
代码的实现
1.开发语言,编译环境
Windows10,Visual Studio 2010,C语言
2.所要用到的头文件
#include <stdio.h> #include <Windows.h> #include <time.h>
代码的实现
3.定义变量及信号量
4.相关线程及方法体
代码的实现
主函数
解决问题的原理及方法
进程模拟和pv操作实现问题
1.采用多线程来模拟进程的并发执行, 创建线程用到的函数是 相关信号量的创建用到的函数是
2.
函数的功能是使线程自愿进入等待状态,
直到一个特定的内核对象变为已通知状态为止
函数的功能是释放互斥对象的控制权,可以理解
为使一个特定的内核对象变为已通知状态
以此来模拟pv操作
读者与写者问题
汇报人:18级计科师范1班李雪梅
目录
PART 01 问题描述 PART 02 解决问题的原理及方法 PART 03 代码实现 PART 04 实现效果
问题描述
读者与写者问题
有读者和写者两组并发进程,共享一个文件,当两个或以上的读 进程同时访问共享数据时不会产生副作用,但若某个写进程和其 他进程(读进程或写进程)同时访问共享数据时则可能导致数据 不一致的错误。因此要求: ①允许多个读者可以同时对文件执行读操作(同步); ②只允许一个写者往文件中写信息(互斥); ③任一写者在完成写操作之前不允许其他读者或写者工作(互斥) ④写者优先(外加条件)
解决问题的原理及方法
写者问题处理办法
1.由于写者与写者、写者与读者之间都是互斥关系,所以这 里可以设置一个写互斥信号量(write)来处理写者进程的 互斥问题
读者-写者问题的实现
![读者-写者问题的实现](https://img.taocdn.com/s3/m/ed824f0d59eef8c75fbfb3f7.png)
《操作系统原理》课程设计任务书题目:读者-写者问题的实现学生姓名:学号:班级:_____________题目类型:软件工程(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 陈映霞”,内容包括任务书、设计文档。
操作系统实验报告——进程同步与互斥
![操作系统实验报告——进程同步与互斥](https://img.taocdn.com/s3/m/47f4f367b5daa58da0116c175f0e7cd185251871.png)
操作系统实验报告——进程同步与互斥一、实验内容本实验主要内容是通过编写程序来实现进程的同步与互斥。
具体来说,是通过使用信号量来实现不同进程之间的同步和互斥。
我们将编写两个进程,一个进程负责打印奇数,另一个进程负责打印偶数,两个进程交替打印,要求打印的数字从1开始,直到100结束。
二、实验原理进程的同步是指多个进程之间按照一定的顺序执行,进程之间互相等待的关系。
而进程的互斥是指多个进程竞争同一个资源,需要通过其中一种方式来避免同时访问共享资源,以免造成数据错乱。
在本实验中,我们使用信号量来实现进程的同步与互斥。
信号量是一个计数器,用于表示一些共享资源的可用数量。
进程在访问共享资源时,需要先对信号量进行操作,当信号量大于0时,表示资源可用,进程可以访问;当信号量等于0时,表示资源不可用,进程需要等待。
进程同步的实现可以通过信号量的P操作与V操作来完成。
P操作用于申请资源,当资源可用时,将计数器减一,并进入临界区;V操作用于释放资源,当资源使用完毕时,将计数器加一,使等待资源的进程能够申请。
进程互斥的实现可以通过信号量的P操作与V操作结合临界区来完成。
当多个进程需要访问共享资源时,需要先进行P操作,进入临界区,访问完毕后进行V操作,离开临界区。
三、实验步骤1.首先,我们需要创建两个进程,一个进程负责打印奇数,另一个进程负责打印偶数。
2. 然后,我们创建一个共享变量count,用来记录打印的数字。
3. 接着,我们创建两个信号量odd和even,用来控制进程的同步与互斥。
odd信号量初始值为1,表示打印奇数的进程可以访问;even信号量初始值为0,表示打印偶数的进程需要等待。
4.编写奇数打印进程的代码,首先进行P操作,判断奇数信号量是否大于0,如果大于0,表示可以打印奇数。
5. 如果可以打印奇数,将count加一,并输出当前的奇数,然后进行V操作,释放偶数打印进程的等待。
6.同样的,编写偶数打印进程的代码,首先进行P操作,判断偶数信号量是否大于0,如果大于0,表示可以打印偶数。
读者-写者问题解答
![读者-写者问题解答](https://img.taocdn.com/s3/m/a06605b369dc5022aaea00a5.png)
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)读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。
操作系统原理课程设计读者-写者问题的实现
![操作系统原理课程设计读者-写者问题的实现](https://img.taocdn.com/s3/m/82952b6fa417866fb84a8ed7.png)
*******************实践教学*******************计算机与通信学院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 个读者或写者。
请用信号量机制分别实现读者优先和写者优先的读者-写者问题。
将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。
操作系统之读者与写者问题(C++)
![操作系统之读者与写者问题(C++)](https://img.taocdn.com/s3/m/2f20c2023186bceb18e8bbbc.png)
printf("第%d位读者正在读。。。\n", myid);
Sleep(2000);//模拟读操作
printf("第%d位读者已完成\n", myid);
WaitForSingleObject(rc_mutex, INFINITE);//对rc互斥访问
ReleaseMutex函数的功能是释放互斥对象的控制权,可以理解为使一个特定的内核对象变为已通知状态。
4.测试及实验结果
4.1 实验结果
图4-1 第一次运行结果图
图4-2 第二次运行结果图
4.2 结果分析
根据图4-1的运行结果来分析,当第二位读者和第二位写者同时存在时,先运行的是写者进程,只有当写者进程完成操作后才能进行读者进程,根据图4-2的运行结果来分析,第一位读者进入后需等第四位写者完成写操作后才能开始读操作。总得来看,该程序得读者与写者得优先级其实是一样的,谁先创建的就谁先运行,但必须等上一个进程完成后才能运行下一个进程。
6.参考文献
[1]张玉生、刘炎、张亚红. C语言程序设计[M].上海交通大学出版社,2004
[2]陆丽娜.计算机操作系统[M].高等教育出版社. 2015.8
[3]李春葆.数据结构教程[M].清华大学出版社,2004
[4].陈向群,向勇等. Windows操作系统原理(第二版) [M]. 机械工业出版社,2004
rc -= 1;//读者数减1
if (rc == 0)
ReleaseMutex(w);//释放写互斥信号量
ReleaseMutex(rc_mutex);//释放互斥信号量rc_mutex
return 1;
实验3--读者-写者问题与进程同步
![实验3--读者-写者问题与进程同步](https://img.taocdn.com/s3/m/f8718ca0f01dc281e43af09f.png)
实验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所示的算法描述。
操作系统实验报告——进程同步与互斥
![操作系统实验报告——进程同步与互斥](https://img.taocdn.com/s3/m/2a680c4c6bd97f192279e9bc.png)
《进程同步与互斥》实验报告实验序号:01 实验项目名称:进程同步与互斥学号姓名专业、班实验地点指导教师时间一、实验目的1、掌握基本的进程同步与互斥算法,理解生产者-消费者问题。
2、学习使用Windows 2000/XP中基本的同步对象,掌握相关API的使用方法。
3、了解Windows 2000/XP中多线程的并发执行机制,实现进程的同步与互斥。
4、设计程序,实现生产者-消费者进程(线程)的同步与互斥;二、实验环境Windows 2000/XP + Visual C++ 6.0三、实验内容以生产者-消费者模型为依据,在Windows 2000/XP环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
四、设计思路和流程框图生产者进程的功能:生产东西,供消费者消费;消费者进程的功能:消费生产者生产的东西。
生产者生产产品并存入缓冲区供消费者取走使用,消费者从缓冲器内取出产品去消费。
在生产者和消费者同时工作时,必须禁止生产者将产品放入已装满的缓冲器内,禁止消费者从空缓冲器内取产品。
五、源程序(含注释)清单#include<windows.h>printf("Consumer %2d finish consuming product %2d\n ",m_serial,m_thread_request[i]);}//离开临界区LeaveCriticalSection(&PC_Critical[BufferPos]);}}六、测试结果以及实验总结1、通过实验进一步了解了基本的进程同步与互斥算法,理解生产者-消费者问题2、掌握了相关API的使用方法。
3、了解到进程是一个可以拥有资源的基本单位,是一个可以独立调度和分派的基本单位。
而线程是进程中的一个实体,是被系统独立调度和分配的基本单位,故又称为轻权(轻型)进程(Light Weight Process)。
进程同步问题总结报告
![进程同步问题总结报告](https://img.taocdn.com/s3/m/b158e61d302b3169a45177232f60ddccda38e680.png)
进程同步问题总结报告一、问题描述进程同步是操作系统中一个重要的问题,它涉及到多个进程在共享资源时如何正确地访问和操作。
在多进程环境中,如果没有正确的同步机制,会导致诸如竞态条件、死锁等问题。
本报告主要探讨进程同步问题及其解决方案。
二、问题分析1. 竞态条件:当多个进程同时访问共享资源,并且至少有一个进程的操作结果被其他进程的操作所覆盖,就会产生竞态条件。
竞态条件可能会导致数据不一致、系统状态不确定等问题。
2. 死锁:死锁是指两个或多个进程在等待对方释放资源,导致系统无法继续执行的情况。
死锁通常是由于资源分配不当、进程请求资源的顺序不一致等原因造成的。
三、解决方案1. 互斥锁(Mutex):互斥锁是一种最基本的同步机制,它允许一个进程在一段时间内独占共享资源。
当一个进程获得互斥锁后,其他进程就不能再获取锁,直到原进程释放锁。
这样可以避免竞态条件。
2. 信号量(Semaphore):信号量是一个计数器,用于控制对共享资源的访问次数。
信号量的值表示当前可用的共享资源数量。
通过调整信号量的值,可以控制进程对共享资源的访问。
3. 条件变量(Condition Variable):条件变量用于进程间的通信,一个进程可以在条件变量上等待,直到另一个进程通过通知操作唤醒它。
条件变量常与互斥锁、信号量等机制结合使用。
4. 读写锁(Read-Write Lock):读写锁允许多个进程同时读取共享资源,但只允许一个进程写入共享资源。
这可以提高并发性能,特别适用于读操作远多于写操作的情况。
5. 栅栏(Barrier):栅栏是一种同步机制,用于确保多个进程在访问共享资源前都达到某一位置。
栅栏类似于一个检查点,所有进程在到达栅栏前都必须等待,直到所有进程都到达栅栏才继续执行。
四、实验结果我们通过实验验证了这些同步机制的正确性和有效性。
实验中,我们设计了一些多进程程序,模拟了竞态条件和死锁情况,然后使用上述同步机制来解决这些问题。
读者写者问题-操作系统课程设计
![读者写者问题-操作系统课程设计](https://img.taocdn.com/s3/m/9bf1c5e779563c1ec4da7132.png)
者写者问题-操作系统课程设计某某大学课程设计报告课程名称:操作系统课程设计设计题目:读者写者问题系别:计算机系专业:计算机科学与技术组别:第四组学生姓名: 某某某学号:起止日期:指导教师:目录1、需求分析 (1)1.1 课程设计题目 (1)1.2课程任务及要求 (1)1.3课程设计思想 (1)1.4软硬件运行环境及开发工具 (2)2、概要设计 (2)2.1程序流程图 (2)2.2所用原理 (3)2.2.1 并发原理 (3)2.2.2 互斥操作原理 (4)2.2.3 面向对象编程编程原理 (4)2.2.4 锁机制原理 (5)2.2.5 线程的原理 (6)2.2.6 读者写者问题的一般应用 (6)3、详细设计 (7)4、调试与操作说明 (16)5、课程设计总结与体会 (18)6、致谢 (19)7、参考文献 (19)1、需求分析1.1课程设计题目课程设计题目:读者写者问题1.2课程任务及要求编写程序实现读者写者算法(读_写互斥,读_读允许,写写互斥)给出解决方案(包括说明设计实现的原理,采用的数据结构等)画出程序的基本结构框图和流程图分析说明每一部分程序的的设计思路实现源代码按期提交完整的程序代码和可执行程序根据要求完成课程设计报告总结1.3课程设计思想读者-写者问题是一个经典的并发程序设计问题。
有两组并发进程:读者和写者,共享文件F,要求:(1)允许多个读者同时对文件执行读操作;(2)只允许一个写者对文件执行写操作;(3)任何写者在完成写操作之前不允许其他读者或写者工作;(4)写者在执行写操作前,应让已有的写者和读者全部退出。
单纯使用信号量不能解决此问题,必须引入计数器readcount对读进程记数。
为了有效的解决读者写者问题,需要引进读者-写者锁,允许多名读者同时以只读的方式存取有锁保护的对象;或一位写者以写方式存取有锁保护的对象。
当一名或多名读者上锁后,此时形成读锁,写者将不能访问有锁保护的对象;当锁被请求者用于写操作时,形成写锁,其他进程的读写操作必须等待。
操作系统进程同步实验报告
![操作系统进程同步实验报告](https://img.taocdn.com/s3/m/af9253930129bd64783e0912a216147917117e20.png)
操作系统进程同步实验报告本实验旨在通过模拟操作系统中进程的同步问题,加深学生对操作系统中进程同步机制的了解和实践能力。
本次实验分为两个部分,第一个部分是使用信号量实现进程同步,第二个部分是使用管程实现进程同步。
第一部分实验:使用信号量实现进程同步本部分实验的目标是使用信号量来实现进程同步,确保资源的互斥访问。
在Linux系统中,信号量是一种用来控制进程同步的机制,可以用于保证共享资源的互斥访问、避免死锁等问题。
具体实验流程如下:1. 定义一个信号量,用于互斥访问共享资源在Linux系统中,使用semget函数可以创建一个信号量集,使用semctl函数可以对信号量进行控制。
```#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#define KEY 1234 // 定义信号量的键值int semid; // 定义信号量标识符union semun{int val; // 信号量的初始值struct semid_ds *buf; // IPC_STAT, IPC_SET操作时用ushort *array; // GETALL, SETALL操作时用};void init_sem(){int ret;union semun semunion;// 创建信号量semid = semget(KEY, 1, IPC_CREAT | 0666);if(semid == -1){perror("semget error");exit(1);}2. 定义生产者和消费者进程,并使用信号量来实现同步在生产者和消费者进程中,需要先对信号量进行P操作,即申请资源,然后进行对共享资源的操作,最后再对信号量进行V操作,即释放资源。
本实验中,共享资源是一个循环缓冲区,生产者进程向其中写入数据,消费者进程从中读取数据。
操作系统:读者-写者问题(C语言winapi)
![操作系统:读者-写者问题(C语言winapi)](https://img.taocdn.com/s3/m/0b76d20fa66e58fafab069dc5022aaea998f41ce.png)
操作系统:读者-写者问题(C语⾔winapi)要求实现:1. 创建⼀个控制台进程,此进程包含n个线程。
⽤这n个线程来表⽰n个读者或写者。
每个线程按相应测试数据⽂件的要求进⾏读写操作。
⽤信号量机制分别实现读者优先和写者优先的读者-写者问题。
2. 读者-写者问题的读写操作限制(包括读者优先和写者优先):1. 写-写互斥,即不能有两个写者同时进⾏写操作。
2. 读-写互斥,即不能同时有⼀个线程在读,⽽另⼀个线程在写。
3. 即可以有⼀个或多个读者在读。
3. 读者优先的附加限制:如果⼀个读者申请进⾏读操作时已有另⼀个读者正在进⾏读操作,则该读者可直接开始读操作。
4. 写者优先的附加限制:如果⼀个读者申请进⾏读操作时已有另⼀写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。
5. 运⾏结果显⽰要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显⽰⼀⾏提⽰信息,以确定所有处理都遵守相应的读写操作限制。
测试数据⽂件格式:测试数据⽂件包括n⾏测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。
每⾏测试数据包括四个字段,各个字段间⽤空格分隔。
第⼀字段为⼀个正整数,表⽰线程序号。
第⼆字段表⽰相应线程⾓⾊,R表⽰读者,W表⽰写者。
第三字段为⼀个正数,表⽰读写操作的开始时间:线程创建后,延迟相应时间(单位为秒)后发出对共享资源的读写申请。
第四字段为⼀个正数,表⽰读写操作的持续时间。
当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。
下⾯是⼀个测试数据⽂件的例⼦:2 W 4 53 R 5 24 R 6 55 W 5.1 3注意:在创建数据⽂件时,由于涉及到⽂件格式问题,最好在记事本中⼿⼯逐个键⼊数据,⽽不要拷贝粘贴数据,否则,本⽰例程序运⾏时可能会出现不可预知的错误。
代码:⽤信号量实现,可先写出P/V操作的伪代码,再根据伪代码翻译C代码。
- 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, // 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,如果信号量小于等于0,那么他一直在循环。
5实现信号量互斥和同步CreateSemaphore用于创建信号量,根据参数的不同可以利用它实现互斥和同步。
ReleaseSemaphore用于释放信号量,使用后相应的信号量加1HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,//SDLONG,lInitialCount, //initial countLONG,lMaximumCount, //maximum countLPCTSTR lpName //object name);ReleaseSemaphore(HANDLE hSemaphore, //handle to semaphoreLONG lRelseaseCount, //cont increment amountLPLONG lpPreviousCount //previous count);三、题目分析将所有的读者和所有的写者分别放进两个等待队列中,当读允许时就让读者队列释放一个或多个读者,当写允许时,释放第一个写者操作。
(1)构筑读者进程和写者进程间的临界区题目中说的一批数据被多个读者、写者共享使用,允许多个读者同时访问这些数据,但是如果有一个写者在访问数据时,就不允许其他读者或写者使用,所以,对这一批数据既要保证读者和写者互斥使用,也要保证写者与写者互斥使用。
也就是说,在读者进程程序中,使用数据的程序段应该构成临界区;在写者进程程序中,使用数据的程序段应该构成临界区。
(2)判定是否是第一个读者根据上面的分析,希望在读者进程中有一个办法能判定请求进入临界区的是否是第一个读者。
如果是第一个读者,就对信号量wsem做P操作,以取得和写者的同步。
为此,设置一个变量rfirst,初值为0.任何一个读者运行时,都现在rfirst上加1,然后判定他是否取值为1.如果是1,则做P(wrt),否则不做。
(3)判定是否是第一个写者原理同(2)判定是否为第一个读者。
(4)写者优先问题的解决需要用到的如下的信号量和变量rsem: 初值为1的互斥信号量,在至少有一个写者准备访问数据时就不允许随后来的读者访问数据wserm: 初值为1的互斥信号量,之后有一个写者访问数据时其他写者和读者就被阻止对数据的访问ReadMutex: 创建写者的互斥信号量,初值为1WriteMutex: 创建读者的互斥信号量,初值为1z: 初值为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);}读者写者图3.1读者-写者的完整流程框图(5)读者优先与写者优先算法相反,有一个读者优先的算法,即只要有读者在读数据,写者被拒绝在临界区外面,如果有源源不断的写者来,但是只要写者不是第一个,那么写者将会永远被拒绝在临界区外面。
wrt::初值为1的互斥信号量,只要有一个写者访问数据,则其他写者和读者就要被阻止对数据的访问。
mutex:保证读者互斥操作first的信号量,初值为1first :读者计数变量,初值为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)读写者进程参见图2.1读者-写者的完整流程图。
(4)同步与互斥WaitForSingleObject(信号量名字,infinite)和ReleaseSemaphore(信号量名字,1,null)用于实现同步于互斥,执行WaitForSingleObject(信号量名字,infinite)信号量相应的信号量减1,执行ReleaseSemaphore(信号量名字,1,null)恢复1。
五、代码及流程//写者优先算法#include <windows.h>#include <ctype.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <malloc.h>#define MAX_PERSON 10#define READER 0#define WRITER 1#define END -1#define R READER #define W WRITERtypedef struct _Person{HANDLE Thread;int Type;int StartTime;int WorkTime;int ID;}Person;Person Persons[MAX_PERSON]; int NumPerson = 0;long CurrentTime= 0;int PersonLists[] = {1,R,1,3,2,W,2,5,/*读写互斥*/3,W,5,5,/*写写互斥*/4,R,3,5,/*写读互斥*/5,R,15,2,/*读读不互斥*/END,};int rfirst = 0;int wfirst = 0;int NumOfReaders = 0;int NumOfWriters = 0;HANDLE rsem;/*初值为1的互斥信号量,在至少有一个写者准备访问数据时就不允许随后来的读者访问数据*/HANDLE wsem;/*初值为1的互斥信号量,之后有一个写者访问数据时其他写者和读者就被阻止对数据的访问*/HANDLE z;/*初值为1的互斥信号量,在至少有一个写着准备访问数据、且后面已经来一个读者时再来的读者将在这个信号量上等待*/HANDLE ReadMutex;/*创建写者的互斥信号量,初值为1*/HANDLE WriteMutex;/*创建读者的互斥信号量, 初值为1*/void CheckPersonList(int *pPersonList);/*查看人数,为创建读写者线程*/ bool CreateReader(int StartTime,int WorkTime);bool CreateWriter(int StartTime,int WorkTime);DWORD WINAPI ReaderProc(LPVOID lpParam);/*读者进程程序*/DWORD WINAPI WriterProc(LPVOID lpParam);/*写着进程程序*/#include "Writerprior.h"int main(){rsem = CreateSemaphore(NULL,1,1,NULL);wsem = CreateSemaphore(NULL,1,1,NULL);z = CreateSemaphore(NULL,1,1,NULL);ReadMutex = CreateSemaphore(NULL,1,1,NULL);WriteMutex = CreateSemaphore(NULL,1,1,NULL);CurrentTime = 0;while(true)//模拟20个时钟周期{CheckPersonList(PersonLists);CurrentTime++;Sleep(600);printf("当前时间= %d:\n",CurrentTime);if(CurrentTime==20)break;}system("pause");CloseHandle(rsem);CloseHandle(wsem);CloseHandle(z);CloseHandle(ReadMutex);CloseHandle(WriteMutex);return 0;}void CheckPersonList(int *pPersonLists){int i=0;int *pList = pPersonLists;bool P;while(pList[0] != END){if(pList[2] == CurrentTime){switch(pList[1]){case R:P = CreateReader(pList[2],pList[3]);//创建一个读者break;case W:P = CreateWriter(pList[2],pList[3]);//创建一个写者break;}if(!P)printf("Create Person %d is wrong\n",pList[0]);}pList += 4; // 数组的指针指向第二个人}}DWORD WINAPI ReaderProc(LPVOID lpParam){Person *pPerson = (Person*)lpParam;pPerson->ID = ++NumOfReaders;WaitForSingleObject(z,INFINITE);//P(z),其余读者在此排队printf("\t\t读者%d 申请读数据...\n",pPerson->ID);WaitForSingleObject(rsem,INFINITE);//P(rsem),一个读者与一个写着再次竞争数据的使用权//printf("Reader %d is requesting the Shared Buffer...\n",pPerson->ID);WaitForSingleObject(ReadMutex,INFINITE);//P(ReadMutex),读者请求进入rfirst临界区rfirst++;if(rfirst == 1)//是否是第一个读者{WaitForSingleObject(wsem,INFINITE);//读者在此处与写者进行同步}ReleaseSemaphore(ReadMutex,1,NULL);//退出rfirst临界区,V(ReadMutex) ReleaseSemaphore(rsem,1,NULL);ReleaseSemaphore(z,1,NULL);//V(z)// 读取所需数据,将现在时间赋值给读者,用以计算结束时间printf("\t\t读者%d 申请成功\n",pPerson->ID);pPerson->StartTime = CurrentTime;printf("\t\t读者%d 正在读数据...\n",pPerson->ID);while(CurrentTime < pPerson->StartTime + pPerson->WorkTime){// 模拟读数据}printf("\t\t读者%d 读完数据退出\n",pPerson->ID);WaitForSingleObject(ReadMutex,INFINITE);rfirst--;if(rfirst == 0) //是最后一个读者?ReleaseSemaphore(wsem,1,NULL);//没有读者了,写者放行ReleaseSemaphore(ReadMutex,1,NULL);//退出读者临界区ExitThread(0);//关闭读者线程return 0;}DWORD WINAPI WriterProc(LPVOID lpParam)//写者进程程序{Person *pPerson = (Person*)lpParam;pPerson->ID = ++NumOfWriters;printf("\t\t写者%d 正在申请写数据...\n",pPerson->ID);WaitForSingleObject(WriteMutex,INFINITE);//请求进入写者临界区wfirst=wfirst++;if(wfirst==1){WaitForSingleObject(rsem,INFINITE);//一个写者在此与读者取得同步}ReleaseSemaphore(WriteMutex,1,NULL);//退出rfirst临界区WaitForSingleObject(wsem,INFINITE);//其他写者在此等候进入写临界区// 读取所需数据,将现在时间赋值给读者,用以计算结束时间pPerson->StartTime = CurrentTime;printf("\t\t写者%d 正在写数据...\n",pPerson->ID);while(CurrentTime < pPerson->StartTime + pPerson->WorkTime){//模拟写数据}printf("\t\t写者%d 写完数据退出\n",pPerson->ID);ReleaseSemaphore(wsem,1,NULL);//退出进入写临界区WaitForSingleObject(WriteMutex,INFINITE);//请求进入wfirst临界区wfirst=wfirst--;if(wfirst==0)//是最后一个写者?{ReleaseSemaphore(rsem,1,NULL);//没有写者了,向读者放行}ReleaseSemaphore(WriteMutex,1,NULL);//退出wfirst临界区ExitThread(0);//关闭写者线程return 0;}bool CreateReader(int StartTime,int WorkTime){DWORD dwThreadID;Person *pPerson = &Persons[NumPerson];pPerson->StartTime = StartTime;pPerson->WorkTime = WorkTime;pPerson->Type = READER;NumPerson++;// 创建一个读者的新线程pPerson->Thread = CreateThread(NULL,0,ReaderProc,(LPVOID)pPerson,0,&dwThreadID);if(pPerson->Thread == NULL)return false;return true;}bool CreateWriter(int StartTime,int WorkTime){DWORD dwThreadID;if(NumPerson >= MAX_PERSON)return false;Person *pPerson = &Persons[NumPerson];pPerson->StartTime = StartTime;pPerson->WorkTime = WorkTime;pPerson->Type = WRITER;NumPerson++;// 创建一个写者的新线程pPerson->Thread = CreateThread(NULL,0,WriterProc,(LPVOID)pPerson,0,&dwThreadID);if(pPerson->Thread == NULL)return false;return true;}六、运行结果图6.1 运行结果结果分析:顺序开始时间(s)执行时间(s)Reader 1 1 32 3 53 15 2Writer 1 2 52 5 5表6.1如上表,第一个读者1到达时间是第1s,执行时间是3s,即在第4s的时候结束,而在第2s的时候就写者1到达。