欢迎来到沃文网! | 帮助中心 分享知识,传播智慧!
沃文网
全部分类
  • 教学课件>
  • 医学资料>
  • 技术资料>
  • 学术论文>
  • 资格考试>
  • 建筑施工>
  • 实用文档>
  • 其他资料>
  • ImageVerifierCode 换一换
    首页 沃文网 > 资源分类 > DOC文档下载
    分享到微信 分享到微博 分享到QQ空间

    山东大学操作系统实验六报告死锁问题.doc

    • 资源ID:979021       资源大小:339.50KB        全文页数:49页
    • 资源格式: DOC        下载积分:20积分
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: QQ登录 微博登录
    二维码
    微信扫一扫登录
    下载资源需要20积分
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,下载更划算!
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    山东大学操作系统实验六报告死锁问题.doc

    1、计算机科学与技术学院操作系统实验报告实验题目:死锁问题在两个城市南北方向之间存在一条铁路,多列火车可以分别从两个城市的车站排队等待进入车道向对方城市行驶,该铁路在同一时间,只能允许在同一方向上行车,如果同时有相向的火车行驶将会撞车。请模拟实现两个方向行车,而不会出现撞车或长时间等待的情况。您能构造一个管程来解决这个问题吗?实验目的: 通过本实验观察死锁产生的现象,考虑解决死锁问题的方法。从而进一步加深对于死锁问题的理解。掌握解决死锁问题的几种算法的编程和调试技术。练习怎样构造管程和条件变量,利用管程机制来避免死锁和饥俄问题的发生。硬件环境: Inter(R)Core(TM)i5-3210M C

    2、PU 2.50GHz 内存:4GB 硬盘:500G软件环境: XUbuntuLinux 操作系统 Gnome 桌面 2.18.3 BASH_VERSION=3.2.33(1)-release gcc version 4.1.2 gedit 2.18.2 OpenOffice 2.3 实验步骤: 1、问题分析:管程-Monitor管程是一种高级抽象数据类型,它支持在它的函数中隐含互斥操作。结合条件变量和其他一些低级通信原语,管程可以解决许多仅用低级原语不能解决的同步问题。利用管程可以提供一个不会发生死锁或饥饿现象的对象;哲学家就餐问题和 Java语言中的 synchronized 对象都是很好的

    3、管程的例子.管程封装了并发进程或线程要互斥执行的函数。为了让这些并发进程或线程在管程内互斥的执行,进入管程的进/线程必须获取到管程锁或二值信号量条件变量 Condition Variables条件变量提供了一种对管程内并发协作进程的同步机制。如果没有条件变量,管程就不会有很有用。多数同步问题要求在管程中说明条件变量。条件变量代表了管程中一些并发进程或线程可能要等待的条件。一个条件变量管理着管程内的一个等待队列。如果管程内某个进程或线程发现其执行条件为假,则该进程或线程就会被条件变量挂入管程内等待该条件的队列。如果管程内另外的进程或线程满足了这个条件,则它会通过条件变量再次唤醒等待该条件的进程或

    4、线程,从而避免了死锁的产生。所以,一个条件变量 C 应具有两种操作 C.wait()和 C.signal()。当管程内同时出现唤醒者和被唤醒者时,由于要求管程内的进程或线程必须互斥执行,因此就出现了两种样式的条件变量:Mesa Style(signal-and-continue):唤醒者进程或线程继续执行,被唤醒者进程或线程等到唤醒者进程或线程阻塞或离开管程后再执行。Hoare Style(signal-and-wait): 被唤醒者进程或线程立即执行,唤醒者进程或线程阻塞,直道被唤醒者阻塞或离开管程后再执行。 实验6 单行道(过桥)问题可以通过管程很好的解决。可以把单行道/桥封装为一个管程类

    5、,桥上通过的车辆是进入管程的进/线程,可以通过创建多个车辆进/线程并随机产生它们的行进方向,并指定桥上可同时行驶的车辆的个数来模拟该问题的各种现场随机情况。一个正确的实验结果应能实现在各种随机现场情况下车辆进程不会逆向上桥(死锁),也不会使车少方向上的车辆无机会上桥(饥饿).2、算法设计说明如下:以下是一个单行道管程类及其方法和属性的大致描述:定义一个单行道管程类:class OneWay public:OneWay();OneWay();void Arrive(int direc);/ 车辆准备上单行道,direc 为行车方向void Cross(int direc);/ 车辆正在单行道上v

    6、oid Quit(int direc);/ 车辆通过了单行道private:int rate;/车速int *maxCars;/最大同向车数int *numCars;/当前正在通过的车辆数int *currentDirec;/当前通过的车辆的方向Condition *OneWayFull; /通过单行道的条件变量Lock *lock;/单行道管程锁;定义一个进入管程的信号量 Sema 类和锁 Lock 类(可参考实验六的示例程序).定义一个单行道管程的条件变量类:class Condition public:Condition(Sema *sema1 , Sema *sema2);Condit

    7、ion();void Wait(Lock *conditionLock,int direc); /过路条件不足时阻塞void Signal( int direc);/唤醒相反方向阻塞车辆private:Sema* queue1; / 一个方向阻塞队列Sema* queue2; / 另一方向阻塞队列Lock* lock;/ 进入管程时获取的锁;Mesa 型条件变量的 Wait 和 Signal 方法:(也可设计成 Haoro 样式)Condition:Wait( Lock *conditionLock,int direct)保存当前条件锁;释放锁;进入所在方向等待队列睡眠;被唤醒后重新获取锁;C

    8、ondition:Signal( Lock *conditionLock)唤醒相反方向队列等待者单行道管程的 Arrive 和 Quit 方法:OneWay:Arrive(int direc)获取管程锁;如果当前方向不是我的方向或者单行道上有车且车辆数大于等于上限数在条件变量上等待;单行道上车辆数加 1;当前方向为我的方向;释放管程锁;OneWay:Quit(int direc)获取管程锁;单行道上车辆数减 1;车辆数为 0唤醒相反方向队列中的等待者释放管程锁主程序main()建立单行道管程;建立多个行车子进程(最好不少于 5 个),每个随机设定一个行车方向;每个子进程作:while(1)单行

    9、道管程-Arrive(direc);单行道管程-Cross(direc);单行道管程-Exit(direc);3、 开发调试过程:在1、单行道最多允许一辆车行驶,不同方向同时到达五辆车。$ ./dp 5 12、单行道最多允许两辆车同向行驶,不同方向同时到达七辆车。./dp 7 2附件:Dp.cc: #include dp.hSema:Sema(int id)sem_id = id;Sema:Sema() int Sema:down()struct sembuf buf;buf.sem_op = -1;buf.sem_num = 0;buf.sem_flg = SEM_UNDO;if(semop

    10、(sem_id,&buf,1) 0) perror(down error );exit(EXIT_FAILURE);return EXIT_SUCCESS;int Sema:up()Sem_uns arg;struct sembuf buf;buf.sem_op = 1;buf.sem_num = 0;buf.sem_flg = SEM_UNDO;if(semop(sem_id,&buf,1) down();/开锁void Lock:open_lock() sema-up();/用于哲学家就餐问题的条件变量Condition:Condition(Sema *s0, Sema *s1) sema

    11、0 = s0; sema1 = s1; void Condition:Wait(Lock *lock,int dir) lock-open_lock(); semadir-down(); lock-close_lock(); void Condition:Signal(int dir) semadir-up(); int dp:get_ipc_id(char *proc_file,key_t key)#define BUFSZ 256FILE *pf;int i,j;char lineBUFSZ,columBUFSZ;if(pf = fopen(proc_file,r) = NULL)perr

    12、or(Proc file not open);exit(EXIT_FAILURE);fgets(line, BUFSZ,pf);while(!feof(pf)i = j = 0;fgets(line, BUFSZ,pf);while(linei = ) i+;while(linei != ) columj+ = linei+;columj = 0;if(atoi(colum) != key) continue;j=0;while(linei = ) i+;while(linei != ) columj+ = linei+;columj = 0;i = atoi(colum);fclose(pf

    13、);return i;fclose(pf);return -1; int dp:set_sem(key_t sem_key,int sem_val,int sem_flg)int sem_id;Sem_uns sem_arg;/测试由 sem_key 标识的信号量是否已经建立if(sem_id=get_ipc_id(/proc/sysvipc/sem,sem_key) 0 )/semget 新建一个信号灯,其标号返回到 sem_idif(sem_id = semget(sem_key,1,sem_flg) 0)perror(semaphore create error);exit(EXIT_F

    14、AILURE);/设置信号量的初值sem_arg.val = sem_val;if(semctl(sem_id,0,SETVAL,sem_arg) 0)perror(semaphore set error);exit(EXIT_FAILURE);return sem_id; char * dp:set_shm(key_t shm_key,int shm_num,int shm_flg)int i,shm_id;char * shm_buf;/测试由 shm_key 标识的共享内存区是否已经建立if(shm_id=get_ipc_id(/proc/sysvipc/shm,shm_key)0)/s

    15、hmget 新建 一个长度为 shm_num 字节的共享内存if(shm_id= shmget(shm_key,shm_num,shm_flg) 0)perror(shareMemory set error);exit(EXIT_FAILURE);/shmat 将由 shm_id 标识的共享内存附加给指针 shm_bufif(shm_buf=(char *)shmat(shm_id,0,0) (char *)0)perror(get shareMemory error);exit(EXIT_FAILURE);for(i=0; ishm_num; i+) shm_bufi = 0; /初始为 0

    16、/共享内存区已经建立,将由 shm_id 标识的共享内存附加给指针 shm_bufif(shm_buf = (char *)shmat(shm_id,0,0) (char *)0) perror(get shareMemory error);exit(EXIT_FAILURE);return shm_buf;/哲学家就餐问题管程构造函数dp:dp(int r, int max) int ipc_flg = IPC_CREAT | 0644; int shm_key = 220; int shm_num = 5; int sem_key = 120; int sem_val = 0; int s

    17、hm_flg = IPC_CREAT|0644; int sem_id; Sema *sema; Sema *sema1; Sema *sema2; rate = r; maxCars = max;/ currentDirec = 1; numCars = 0; /共享内存,保存当前车辆数 buff_ptr = (int*)set_shm(shm_key+, shm_num, shm_flg); put_ptr = (int *) set_shm(shm_key, 1, shm_flg); buff_ptr*put_ptr = 0; /车辆数 buff_ptr*put_ptr + 1 = 0;

    18、 /记录是否为第一辆车 buff_ptr*put_ptr + 2 = 0; /当前方向超出最大车辆数 buff_ptr*put_ptr + 3 = 0; /反方向车辆数 buff_ptr*put_ptr + 4 = 0; /记录当前方向 /5 个中同时可以有 2 个在就餐,建立一个初值为 2 的用于锁的信号灯 if(sem_id = set_sem(sem_key+,1,ipc_flg) 0) perror(Semaphor create error); exit(EXIT_FAILURE); sema = new Sema(sem_id); lock = new Lock(sema); /为

    19、每个哲学家建立初值为 0 的用于条件变量的信号灯 if(sem_id = set_sem(sem_key+,sem_val,ipc_flg) 0) perror(Semaphor create error); exit(EXIT_FAILURE); sema1 = new Sema(sem_id); if(sem_id = set_sem(sem_key+,sem_val,ipc_flg) close_lock();/ numCars = getNum(); mutex-down(); count = buff_ptr*put_ptr + 1; mutex-up(); if(count = 0

    20、) currentDirec = direc; mutex-down(); buff_ptr*put_ptr + 4 = direc; buff_ptr*put_ptr + 1 = +count; mutex-up(); printf(%d号车从%d方向等待单行道n, getpid(), direc); mutex-down(); currentDirec = buff_ptr*put_ptr + 4; mutex-up(); if(currentDirec != direc) mutex-down(); count = buff_ptr*put_ptr + 3; buff_ptr*put_p

    21、tr + 3 = +count; mutex-up(); con-Wait(lock, direc); sleep(1);/ currentDirec = direc; lock-open_lock();void dp:Cross(int direc) int count, i; lock-close_lock(); for(i = 0; i = maxCars) mutex-down(); count = buff_ptr*put_ptr + 2; buff_ptr*put_ptr + 2 = +count; mutex-up(); con-Wait(lock, direc); addNum

    22、(); printf(%d号车从%d方向进入单行道-n, getpid(), direc); sleep(1); numCars = getNum(); printf(%d号车从%d方向通过单行道,道上车数:%dn, getpid(), direc, numCars); sleep(rate); lock-open_lock();void dp:Leave(int direc) int count, num; lock-close_lock(); printf(%d号车从%d方向离开单行道n, getpid(), direc); decNum(); sleep(1); numCars = ge

    23、tNum(); mutex-down(); count = buff_ptr*put_ptr + 3; num = buff_ptr*put_ptr + 2; mutex-up();/ printf(count:%dn, count);/ printf(num:%dn, num);/ printf(numCars:%dn, numCars); if(numCars = 0 & count != 0) / printf(唤醒方向%dn, 1 - direc); while(count-) con-Signal(1 - direc); mutex-down(); buff_ptr*put_ptr

    24、+ 4 = 1 - direc; buff_ptr*put_ptr + 3 = buff_ptr*put_ptr + 2; buff_ptr*put_ptr + 2 = 0; buff_ptr*put_ptr = 0; mutex-up(); else if(numCars = 0 & num != 0) / printf(唤醒同方向%dn, direc); while(num-) con-Signal(direc); mutex-down(); buff_ptr*put_ptr + 2 = 0; buff_ptr*put_ptr = 0; mutex-up(); lock-open_lock

    25、();dp:dp() int dp:getNum() mutex-down(); int num = buff_ptr*put_ptr; mutex-up(); return num;void dp:addNum() mutex-down(); int num = buff_ptr*put_ptr; buff_ptr*put_ptr = +num; mutex-up();void dp:decNum() mutex-down(); int num = buff_ptr*put_ptr; buff_ptr*put_ptr = -num; mutex-up();/ 哲学家就餐问题并发执行的入口in

    26、t main(int argc,char *argv) dp *tdp; /哲学家就餐管程对象的指针/ int pid5; /5 个哲学家进程的进程号 int cars; int dir;/ int pid5; int pid; int max = 2; int rate = 3;/ rate = (argc 1) ? atoi(argv1) : 3 ; cars = (argc 1) ? atoi(argv1) : 5; max = (argc 2) ? atoi(argv2) : 2; tdp = new dp(rate, max); /建立一个哲学家就餐的管程对象 start: if(p

    27、id = fork() = 0) srand(getpid(); dir = rand() % 2; tdp-Arrive(dir); tdp-Cross(dir); tdp-Leave(dir); else if(-cars) goto start; return 0; Dp.h: #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef union semuns int val; Sem_uns

    28、; enum State waiting, running; /哲学家管程中使用的信号量class Semapublic: Sema(int id); Sema(); int down(); /信号量加 1 int up(); /信号量减 1private: int sem_id; /信号量标识符;/哲学家管程中使用的锁class Lockpublic: Lock(Sema *lock); Lock(); void close_lock(); void open_lock();private: Sema *sema; /锁使用的信号量;/哲学家管程中使用的条件变量class Condition

    29、 public: Condition(Sema *sema1 , Sema *sema2); Condition(); void Wait(Lock *conditionLock,int direc); /过路条件不足时阻塞 void Signal( int direc); /唤醒相反方向阻塞车辆private: Sema* sema2; / 一个方向阻塞队列/ Sema* queue2; / 另一方向阻塞队列 Lock* lock; / 进入管程时获取的锁; /哲学家管程的定义class dppublic: dp(int rate, int max); dp(); void Arrive(i

    30、nt direc); / 车辆准备上单行道,direc 为行车方向 void Cross(int direc); / 车辆正在单行道上 void Leave(int direc); / 车辆通过了单行道 int getNum(); void addNum(); void decNum(); /建立或获取 ipc 信号量的一组函数的原型说明 int get_ipc_id(char *proc_file,key_t key); int set_sem(key_t sem_key,int sem_val,int sem_flag); /创建共享内存,放哲学家状态 char *set_shm(key_

    31、t shm_key,int shm_num,int shm_flag);private: int rate; /车速 int maxCars; /最大同向车数 int numCars; /当前正在通过的车辆数 int currentDirec; /当前通过的车辆的方向 Condition *con; /通过单行道的条件变量 Lock *lock; /单行道管程锁 int* buff_ptr; int* put_ptr; Sema *mutex;Makefile:head = dp.hsrcs = dp.ccobjs = dp.oopts = -w -g -call: dpdp: $(objs)g+ $(objs) -o dpdp.o: $(srcs) $(head)g+ $(opts) $(srcs)clean:rm dp *.o


    注意事项

    本文(山东大学操作系统实验六报告死锁问题.doc)为本站会员(风****)主动上传,沃文网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知沃文网(点击联系客服),我们立即给予删除!




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服点击这里,给沃文网发消息,QQ:2622162128 - 联系我们

    版权声明:以上文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如有侵权请立即联系:2622162128@qq.com ,我们立即下架或删除。

    Copyright© 2022-2024 www.wodocx.com ,All Rights Reserved |陕ICP备19002583号-1

    陕公网安备 61072602000132号     违法和不良信息举报:0916-4228922