同步机构实验_第1页
同步机构实验_第2页
同步机构实验_第3页
同步机构实验_第4页
同步机构实验_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、软件1401 吴帅帅 3140608020实验四 同步机构一、实验题目模拟PV操作同步机构,且用PV操作解决生产者消费者问题。提示:(1) PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。这两条原语是如下的两个过程:procedure p (var s: semaphore);begin s:=s-1;if s<0 then W(s)end pprocedure v (var s: semaphor

2、e);begin s: =s+1;if s<=0 then R(s)end V其中W(s)表示将调用过程的进程置为等待信号量s的状态;R(s)表示释放一个等待信号量s的进程。在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实验中可把上述的semaphore直接改成integer。(2)生产者消费者问题。假定有一个生产者和消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。消费者每次从缓冲器内取出一件产品去消费。禁止生产者将产品放入已满的缓冲器内,禁止消费者从空缓冲器内取产品。假定缓冲器内可同时存放10件产品。那么,用PV操作来实现生产者和

3、消费者之间的同步,生产者和消费者两个进程的程序如下:B:array 0.9 of products;s1,s2: semaphore;IN, out; integer;IN:=0;out:=0;cobeginprocedure producer;c: products;beginL1:produce (c);p (s1);BIN:=C;IN:=(IN+1)mod 10;v(s2);goto L1end;procedure consumer;x: products;beginL2:P(s2);x:=Bout;out:=(out+1) mod 10;v(s1);consume(x);goto L2

4、end;coend其中的semaphore和products是预先定义的两个类型,在模拟实现中semaphore用integer或char等代替。(3)进程控制块PCB。为了纪录进程执行时的情况,以及进程让出处理器后的状态,断点等信息,每个进程都有一个进程控制块PCB。在模拟实验中,假设进程控制块的结构如图4-1。其中进程的状态有:运行态、就绪态、等待态和完成态。当进程处于等待态时,在进程控制块PCB中要说明进程等待原因(在模拟实验中进程等待原因为等待信号量s1或s2);当进程处于等待态或就绪态时,PCB中保留了断点信息,一旦进程再度占有处理器则就从断点位置继续运行;当进程处于完成状态,表示进

5、程执行结束。进程名状态等待原因断点 图4-1 进程控制块结构·ZA(4)处理器的模拟。计算机硬件提供了一组机器指令,处理器的主要职责是解释执行机器指令。为了模拟生产者和消费者进程的并发执行,我们必须模拟一组指令和处理器职能。模拟的一组指令见图4-2,其中每条指令的功能由一个过程来实现。用变量PC来模拟“指令计数器”,假设模拟的指令长度为1,每执行一条模拟指令后,PC加1,指出下一条指令地址。使用模拟的指令,可把生产者和消费者进程的程序表示为图4-3的形式。定义两个一维数组PA0.4和SA0.4,每一个PAi存放生产者程序中的一条模拟指令执行的入口地址;每个SAi存放消费者程序中的一条

6、模拟指令执行的入口地址。于是模拟处理器执行一条指令的过程为:取出PC之值,按PAPC 或SAPC得模拟指令执行的入口地址,将PC之值加1,转向由入口地址确定的相应的过程执行。(5)程序设计本实验中的程序由三部分组成:初始化程序、处理器调度程序、模拟处理器指令执行程序。各部分程序的功能及相互间的关系由图4-4至图4-7指出。模拟的指令功能P(s)执行P操作原语V(s)执行v操作原语putBIN:=product;IN:=(IN+1) mod 10GETX:=Bout;out:=(out+1) mod 10produce输入一个字符放入C中consume打印或显示x中的字符GOTO LPC: LN

7、OP空操作图4-2 模拟的处理器指令序号生产者程序消费者程序0produceP(s2)1P(s1)GET2PUTV(s1)3V(s2)consume4goto 0goto 0图4-3 生产者和消费者程序初始化程序:模拟实验的程序从初始化程序入口启动,初始化工作包括对信号量S1、S2赋初值,对生产者、消费者进程的PCB初始化。初始化后转向处理器调度程序,其流程如图4-4处理器调度程序:在计算机系统中,进程并发执行时,任一进程占用处理器执行完一条指令后就有可能被打断而让出处理器由其他进程运行。故在模拟系统中也类似处理,每当执行一条模拟的指令后,保护当前进程的现场,让它成为非运行状态,由处理器调度程

8、序按随机数再选择一个就绪进程占用处理器运行。处理器调度程序流程见图4-5。开始初始化信号量S1,S2S1:=10,S2:=0处理器调度程序生产者和消费者进程的PCB中状态为就绪,断点为0将现行进程置为生产者进程,PC:=0结束图 4-4 初始化流程模拟处理器指令执行程序:按“指令计数器”PC之值执行指定的质量,且PC加1指向下一条指令。模拟处理器指令执行的程序流程见图4-6和4-7。另外,为了使得模拟程序有一个结束条件,在图4-6中附加了“生产者运行结束”的条件判断,模拟时可以采取人工选择的方法实现。图4-7给出了P(S)和V(S)模拟指令执行过程的流程。其他模拟指令的执行过程已在图4-2中指

9、出。二、源程序datatype.py:# 进程块class PCB(object): def _init_(self, name, status): = name # 进程名 self.status = status # 进程状态 self.reason = None # 等待原因 self.point = 0 # 断点 def _str_(self): return "PCB: name=name, status=sta, reason=rea, point=poi" .format(name=, sta=self.status, r

10、ea=self.reason, poi=self.point)# P(S) 操作def p(pcb, semp): """ 模拟P(S) :param pcb: 调用P的进程 :param semp: 信号量 :return: """ if semp"value" <= 0: # 将调用p的进程设置为等待s的状态 pcb.status = "等待" pcb.reason = semp else: # 将调用p的进程设置为 就绪 semp"value" -= 1 pcb.

11、status = "就绪"# V(S) 操作def v(pcb, semp, pcbs): """ 模拟V(S) :param pcb: 调用P的进程 :param semp: 信号量 :param pcbs: 进程队列 :return: """ semp"value" += 1 if semp"value" > 0: # 找一个等待s信号量的进程置为就绪态 for x in pcbs: if x.status = "等待" and x.reason

12、 = semp: x.status = "就绪" break else: # 将调用V(s)过程的进程置为就绪 pcb.status = "就绪"def put(buffer, pin, c): # BIN:=product;IN:=(IN+1) mod 10 bufferpin = c return (pin + 1) % 10def get(buffer, pout): # X:=Bout;out:=(out+1) mod 10 result = bufferpout pout = (pout + 1) % 10 return result, pou

13、tdef produce(str_input, str_point): # 从输入的字符串中提取一个字符 c = str_inputstr_point str_point += 1 return c, str_pointdef consume(c): # 打印或显示x中的字符 print(" ", c)def goto(n): # PC: L return ndef nop(): # 空操作 passmain.py:import randomfrom operate.pv.datatype import *if _name_ = "_main_": #

14、信号量 s1 = dict(name="s1", value=10) s2 = dict(name="s2", value=0) # 生产者程序 PA = (produce, p, put, v, goto) # PA = (produce, nop, put, nop, goto) # 消费者程序 CA = (p, get, v, consume, goto) # CA = (nop, get, nop, consume, goto) producer = PCB("生产者", "就绪") consumer =

15、PCB("消费者", "就绪") # 进程队列 pcbs = list() pcbs.append(producer) pcbs.append(consumer) str_input = input("请输入要打印的字符串:") # str_input = "AB" str_point = 0 # 生产者和消费者共同操作的数据集合 长度为10 buffer = 0*10 pin = 0 pout = 0 while True: # 注释的部分是为了循环一步一步的执行 # flag = (input("是否

16、运行:(y/n)").lower() # if flag = "n": # break # elif flag = "y": # pass # else: # continue ran = random.randint(0, 1) # 随机调用 pcb_current = pcbsran # 当前调用的进程 print("Before: ", pcb_current) pc = pcb_current.point if pcb_current.status = "等待" or pcb_current.st

17、atus = "完成": continue pcb_current.status = "运行" # 选择操作序列 if pcb_ = "生产者": f = PApc elif pcb_ = "消费者": f = CApc # 执行具体的操作 pc += 1 pcb_current.point = pc if f = produce: c, str_point = produce(str_input, str_point) print(" produce: &

18、quot;, "字符c = ", c) elif f = p and pcb_current = producer: p(producer, s1) print(" p(s1): ", "信号量s1 = ", s1"value") elif f = p and pcb_current = consumer: p(consumer, s2) print(" p(s2): ", "信号量s2 = ", s2"value") elif f = put: pin

19、= put(buffer, pin, c) print(" put: ", "共享变量buffer = ", buffer) elif f = get: temp, pout = get(buffer, pout) print(" get: ", "取出的字符c = ", temp) elif f = v and pcb_current = producer: v(producer, s2, pcbs) print(" v(s2): ", "信号量s2 = ", s2&quo

20、t;value") elif f = v and pcb_current = consumer: v(consumer, s1, pcbs) print(" v(s1): ", "信号量s1 = ", s1"value") elif f = consume: consume(temp) print(" consume") elif f = goto: pc = goto(0) pcb_current.point = pc print(" goto 0") print("Aft

21、er: ", pcb_current) print() # 判断生产者是否完成 当读取了所有字符 and 生产者进程运行结束时设为完成 if str_point = len(str_input) and producer.point = 0: producer.status = "完成" # 结束循环 if producer.status = "完成" and consumer.status = "等待": print("程序结束了。") break三、运行结果D:Python3.5python.exe

22、D:/MyCodeStorage/PyCharmProjects/Learn/operate/pv/main.py请输入要打印的字符串:ABBefore: PCB: name=生产者, status=就绪, reason=None, point=0 produce: 字符c = AAfter: PCB: name=生产者, status=运行, reason=None, point=1Before: PCB: name=生产者, status=运行, reason=None, point=1 p(s1): 信号量s1 = 9After: PCB: name=生产者, status=就绪, re

23、ason=None, point=2Before: PCB: name=消费者, status=就绪, reason=None, point=0 p(s2): 信号量s2 = 0After: PCB: name=消费者, status=等待, reason='value': 0, 'name': 's2', point=1Before: PCB: name=消费者, status=等待, reason='value': 0, 'name': 's2', point=1Before: PCB: nam

24、e=生产者, status=就绪, reason=None, point=2 put: 共享变量buffer = 'A', 0, 0, 0, 0, 0, 0, 0, 0, 0After: PCB: name=生产者, status=运行, reason=None, point=3Before: PCB: name=消费者, status=等待, reason='value': 0, 'name': 's2', point=1Before: PCB: name=消费者, status=等待, reason='value

25、9;: 0, 'name': 's2', point=1Before: PCB: name=生产者, status=运行, reason=None, point=3 v(s2): 信号量s2 = 1After: PCB: name=生产者, status=运行, reason=None, point=4Before: PCB: name=消费者, status=就绪, reason='value': 1, 'name': 's2', point=1 get: 取出的字符c = AAfter: PCB: name=消

26、费者, status=运行, reason='value': 1, 'name': 's2', point=2Before: PCB: name=生产者, status=运行, reason=None, point=4 goto 0After: PCB: name=生产者, status=运行, reason=None, point=0Before: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=2 v(s1): 信

27、号量s1 = 10After: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=3Before: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=3 A consumeAfter: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2

28、9;, point=4Before: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=4 goto 0After: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=0Before: PCB: name=生产者, status=运行, reason=None, point=0 produce: 字符c = BAfter: PCB: name

29、=生产者, status=运行, reason=None, point=1Before: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=0 p(s2): 信号量s2 = 0After: PCB: name=消费者, status=就绪, reason='value': 0, 'name': 's2', point=1Before: PCB: name=生产者, status=运行, reason=None, poin

30、t=1 p(s1): 信号量s1 = 9After: PCB: name=生产者, status=就绪, reason=None, point=2Before: PCB: name=生产者, status=就绪, reason=None, point=2 put: 共享变量buffer = 'A', 'B', 0, 0, 0, 0, 0, 0, 0, 0After: PCB: name=生产者, status=运行, reason=None, point=3Before: PCB: name=消费者, status=就绪, reason='value&#

31、39;: 0, 'name': 's2', point=1 get: 取出的字符c = BAfter: PCB: name=消费者, status=运行, reason='value': 0, 'name': 's2', point=2Before: PCB: name=生产者, status=运行, reason=None, point=3 v(s2): 信号量s2 = 1After: PCB: name=生产者, status=运行, reason=None, point=4Before: PCB: name=

32、消费者, status=运行, reason='value': 1, 'name': 's2', point=2 v(s1): 信号量s1 = 10After: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=3Before: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=3 B cons

33、umeAfter: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=4Before: PCB: name=生产者, status=运行, reason=None, point=4 goto 0After: PCB: name=生产者, status=运行, reason=None, point=0Before: PCB: name=生产者, status=完成, reason=None, point=0Before: PCB: name=生产者, status=完成

34、, reason=None, point=0Before: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=4 goto 0After: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=0Before: PCB: name=消费者, status=运行, reason='value': 1, 'name': 's2', point=0 p(s2): 信号量s2 = 0After: PCB: name=消费者, status=就绪, reason='value': 0, 'name': 's2', point=1Before: PCB: name=消费者, status=就绪, reason='value': 0, 'name': 's2', point=1 get: 取出的字符c = 0After: PCB:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论