ImageVerifierCode 换一换
格式:DOCX , 页数:19 ,大小:235.11KB ,
资源ID:5798306      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5798306.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(实验二线程与同步 nachos02.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

实验二线程与同步 nachos02.docx

1、实验二线程与同步 nachos02实验报告 2302010220不可不戒一、实验目的实现Nachos的同步机制:锁和条件变量,并利用这些同步机制实现几个基础工具类二实验内容&设计思想&代码首先根据老师提供的文档,对必要的文件进行了理解后进行实验1.实现锁机制和条件变量,并利用这些同步机制将实验一中所实现双向有序链表类修改成线程安全的A使用Thread:Sleep实现锁机制和条件变量在每一个函数(操作)开始时先开中断,结束后在关中断。1.锁LockAcquire()申请锁当锁lockValue=false,说明锁不可用,当前线程进入睡眠状态。当锁lockValue=true,说明锁可用,当前线程

2、获得该锁,继续运行。 Void Lock:Acquire() /ASSERT(!isHeldByCurrentThread(); IntStatus oldLevel=interrupt-SetLevel(IntOff); while(lockValue)/lock not available queue-Append(void *)currentThread); currentThread-Sleep(); lockValue=true;/lock available owner=currentThread;/record the new owner of the lock (void) i

3、nterrupt-SetLevel(oldLevel);Release() 释放锁(注意:只有拥有锁的线程才能释放锁) lockValue=true 如果有其它线程等待该锁,将其中的一个唤醒,进入就绪态。 bool isHeldByCurrentThread()用于判定当前进程是否是锁的持有者。 void Lock:Release() Thread *thread; ASSERT(isHeldByCurrentThread(); IntStatus oldLevel=interrupt-SetLevel(IntOff); thread=(Thread *)queue-Remove(); if(

4、thread !=NULL) scheduler-ReadyToRun(thread); lockValue=false; owner=NULL; (void) interrupt-SetLevel(oldLevel); 2. 条件变量ConditionWait、Signal以及BroadCast,所有的这些操作必须在当前线程获得一个锁的前提下而且所有对一个条件变量进行的操作必须建立在同一个锁的前提下Wait() 线程等待条件变量 释放该锁 进入睡眠状态 重新申请该锁 void Condition:Wait(Lock* conditionLock) ASSERT(conditionLock-i

5、sHeldByCurrentThread(); IntStatus oldLevel=interrupt-SetLevel(IntOff); conditionLock-Release(); queue-Append(void *)currentThread); currentThread-Sleep(); conditionLock-Acquire(); (void)interrupt-SetLevel(oldLevel); Signal() 唤醒一个等待该条件变量的线程(如果存在的话) void Condition:Signal(Lock* conditionLock) Thread *t

6、hread; ASSERT(conditionLock-isHeldByCurrentThread(); IntStatus oldLevel=interrupt-SetLevel(IntOff); thread=(Thread *)queue-Remove(); if(thread !=NULL) scheduler-ReadyToRun(thread); (void)interrupt-SetLevel(oldLevel); /make thread ready,comsuming the V immediately BroadCast() 唤醒所有等待该条件变量的线程(如果存在的话) v

7、oid Condition:Broadcast(Lock* conditionLock) Thread *thread; ASSERT(conditionLock-isHeldByCurrentThread(); IntStatus oldLevel=interrupt-SetLevel(IntOff); thread=(Thread *)queue-Remove(); while(thread !=NULL) scheduler-ReadyToRun(thread); thread=(Thread *)queue-Remove(); (void)interrupt-SetLevel(oldL

8、evel); B使用Semaphore实现锁机制和条件变量1.不需要自行考虑关中断和阻塞队列维护等问题2.Semaphore与条件变量的区别:A.如果在调用Semaphore:P()前调用Semaphore:V() 则V操作的效果将积累下来B.而如果在调用Condition:Wait()前调用Condition:Signal()则Signal操作的效果将不积累3.锁机制直接调用P和V操作,条件变量类似使用Thread:Sleep实现4.在头文件中加入了指向Semaphore变量的指针,用于实现Semaphore实现锁机制和条件变量。void Lock:Acquire() sem_lock-P(

9、); owner=currentThread;void Lock:Release() ASSERT(isHeldByCurrentThread(); owner=NULL; sem_lock-V();void Condition:Wait(Lock* conditionLock) ASSERT(conditionLock-isHeldByCurrentThread(); conditionLock-Release(); wait_count_thread+; sem_condition-P(); conditionLock-Acquire();void Condition:Signal(Loc

10、k* conditionLock) ASSERT(conditionLock-isHeldByCurrentThread(); if(wait_count_thread0) sem_condition-V(); wait_count_thread-; if(wait_count_threadisHeldByCurrentThread(); while(wait_count_thread-) sem_condition-V(); if(wait_count_thread Acquire(); . if(flag) while (IsEmpty()/dllist is empty sleep_co

11、ndition-Wait(sleep_lock);/wait else if(IsEmpty() return NULL; . if(err_type=4) / printf(Remove errorn); currentThread-Yield(); . if(flag) sleep_lock-Release(); .2.实现一个线程安全的表结构A在头文件synch.h中加入bool lockValue标记锁是否可用;Thread *owner用于判定锁是否为当前线程所有;B在初始化table时要创建新的lock锁变量,在析构函数中将其删除即可C要实现线程安全关键是Alloc函数与get函数

12、,在执行时要加入锁机制,以免被线程中断二导致错误。Alloc要求往Table中加入Object,如果满了则返回-1int Table:Alloc(char *obj) if(flag=1) tableLock-Acquire(); for(int i=0;iYield(); tablei=obj; if(flag=1) tableLock-Release(); return i; if(flag=1) tableLock-Release(); return -1;Release()函数是从Table中删除tableindexvoid Table:Release(int index,int wh

13、ich,int i) if(flag=1) tableLock-Acquire(); if(index=0 & indexRelease();3.实现一个大小受限的缓冲区A主要设计思想参考课本5.3.2节生产者/消费者问题。B.三个不同信号量的初始化 n=new Semaphore(used,1);/缓冲区中的项数 s=new Semaphore(sem,0);/用于实施互斥e=new Semaphore(empty,maxsize);/空闲空间的数目C.Buffer 实现方法 semaphone & 使用Semaphore实现锁机制和条件变量注:semaphone见代码注释1.Read()从

14、缓存区读取 void BoundedBuffer:Read(void *data,int size) int *r=(int *)data; while(size-) if(flag=1) /若readout=writein:缓冲区没有可读数据 sem_Lock-Acquire(); while(writein=readout) /printf(wait r%dn,size); bufferEmpty-Wait(sem_Lock); / n-P(); / s-P(); *r+=Bufferreadout; readout=(readout+1)%Buffersize; if(flag=1) b

15、ufferFull-Broadcast(sem_Lock);/buffer is not full,wake up wait writing threads sem_Lock-Release(); / s-V(); / e-V(); 2.Write()函数向缓存区写入数据void BoundedBuffer:Write(void *data,int size) int *w=(int *)data; while(size-) if(flag=1) / 若(writein+1)%Buffersize = readout:缓冲区满。注意:这里有一个空间未被使用 sem_Lock-Acquire()

16、; while(writein+1)%Buffersize=readout) / printf(wait w%dn,size); bufferFull-Wait(sem_Lock); / e-P(); / s-P(); Bufferwritein=*w+; writein=(writein+1)%Buffersize; if(flag=1) bufferEmpty-Broadcast(sem_Lock);/buffer is not empty,wake up wait writing threads sem_Lock-Release(); / s-V(); / n-V(); /每次写入1by

17、tes,就有可能线程切换.读取就会乱序4.关于测试 代码见threadtest.cc二、实验结果相关参数说明:-rs causes Yield to occur at random(but repeatable)spots 修改system.cc void Initalize(int argc,char *argv) bool=randomYield=TRUE1.dllist.cc测试结果 Lock & Condition 实现方法:sleep+中断禁止与启用./nachos -q 2 -t 2 -n 5 -e 0 -rs 2 flag=1 使用锁机制 e=0 没有错误./nachos -q

18、2 -t 2 -n 5 -e 0 -rs 2 flag=0 不使用锁机制e=0 没有错误./nachos -q 2 -t 2 -n 5 -e 0 -rs 2 flag=1 使用锁机制 e=4 有错误./nachos -q 2 -t 2 -n 5 -e 0 -rs 2 flag=0 不用锁机制 e=4 有错误 Dllist.cc 测试 使用Semaphore实现锁机制和条件变量./nachos -q 2 -t 2 -n 5 -e 4 flag=0 不使用锁./nachos -q 2 -t 2 -n 5 -e 4 flag=1 使用锁2.Table测试结果./nachos -q 3 -t 2 -r

19、s 2 flag=1 使用锁机制 结果没问题./nachos -q 3 -t 2 -rs 2 falg=0 不使用锁 结果出现错误 3.BoundedBuffer测试结果 实现方法semaphone./nachos -q 4 -t 5 -rs 3 flag=1 使用信号量./nachos -q 4 -t 5 -rs 3 flag=0 不使用信号量让每一个线程往缓存区写入当前线程号:实现方法 lock & condition三、实验中遇到的问题&总结问题:1. 开始线程不能随机切换,(-rs在助教的帮助下解决) 解决:删除nachos-3.4,重新编译。2. 在链表加锁时,一开始忘记对链表为空的

20、情况进行判定,出现了错误解决:在链表中对有可能因为链表为空的情况加入判断,如果出现空则调用Wait等待。在插入线程执行完以后待用Signal唤醒的等待的进程。3. 在对Table进行操作时,定义了多线程共享table_arr数组,结果一直出错,原来多线程共享全局变量的值会被修改,解决:定义局部变量table_arr数组。4. 在Broadcast 唤醒等待的线程,while()循环后wait_count_thread可能小于0, 当小于0时没赋值0,出现睡死情况。 解决:while()结束判断wait_count_thread是否小于0 ,小于0赋值为0.5. 总结:通过本次实验让我们对信号量的工作机制有了更加深入的理解,可以从线程的观点来考察不同信号量对线程的影响,了解了操作系统对线程并发性的处理过程,对操作系统的架构有了了解。实验分工:

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1