操作系统死锁问题之单行道问题.docx
- 文档编号:24238774
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:21
- 大小:19.64KB
操作系统死锁问题之单行道问题.docx
《操作系统死锁问题之单行道问题.docx》由会员分享,可在线阅读,更多相关《操作系统死锁问题之单行道问题.docx(21页珍藏版)》请在冰豆网上搜索。
操作系统死锁问题之单行道问题
软件学院操作系统实验报告
实验题目:
死锁问题之单行道问题
学号:
1043
日期:
2014年5月15日
班级:
2012级软件5班
姓名:
杜肖兵
Email:
实验目的:
本实验观察死锁产生的现象,考虑解决死锁问题的方法。
从而进一步加深对于死锁问题的理解。
掌握解决死锁问题的几种算法的编程和调试技术。
练习怎样构造管程和条件变量,利用管程机制来避免死锁和饥俄问题的发生。
硬件环境:
Ubuntu11.10
软件环境:
bash终端
vi编辑器
实验步骤:
1.掌握终端的基本命令;
2.掌握vi编辑器的接本使用方法;
3.掌握C语言基本语法;
4.掌握示例程序;
5.编写题目要求的代码;
代码分析:
为了解决本实验的死锁问题,使用c++中的管程。
通过控制管程的信号来确定当前单行道上的车辆情况。
(1)每一辆车请求单行道,如果,单行道上没有车,那么就进入单行道,并且将单行道的方向改为当目前该辆车的方向;
(2)如果单行道上有车并且这辆车的方向与单行道的方向相同那么判断单行道上车辆的数目,如果carNum=maxNum那么此时单行道已经满了,这两策划就会阻塞在目前的信号量上,并且设置一个标志位表示有一辆同向的车等待进入单行道;如果carNum (3)如果这辆车的方向和单行道的方向相反,那么这辆车会被阻塞在自己条件上的信号量上,并且设置一个标志位,表示当前有反向的车等待进入单行道。 (4)每一辆车离开单行道时必须唤醒等待的车辆。 (5)定义Arrive(),Cross(),Leave()三个函数 (6)通过mutex->down();Count=buff_ptr[*put_ptr+1];mutex->up();判断是否为第一辆车,然后如果是第一辆车要说要设定单行道的方向currentDirec=direc;mutex->down();buff_ptr[*put_ptr+4]=direc设置单行道的方向,buff_ptr[*put_ptr+1]=++count修改目前单行道上的车辆数; (7)在每一个相应的函数里,实现相应的功能,Arrive()函数中判断车辆数,方向,修改单行道方向;在cross()函数中判断几辆车通过单行道,方向如何,从哪个方向进入单行道从哪个方向通过单行道;Leave()函数,判断车辆从哪个方向离开,并且唤醒等待的进程。 运行结果: 在第一行参数设定一共有几辆车,单行道的maxNum,通过的速度 online@online-Lenovo: ~/dxb/test6$./Transport731 5216号车从西方向等待单行道 online@online-Lenovo: ~/dxb/test6$5217号车从东方向等待单行道 downerror: Invalidargument 5218号车从西方向等待单行道 5222号车从东方向等待单行道 downerror: Invalidargument 5221号车从西方向等待单行道 5220号车从西方向等待单行道 5219号车从东方向等待单行道 5216号车从西方向进入单行道 downerror: Invalidargument 5216号车从西方向通过单行道,道上车数: 1 5218号车从西方向进入单行道 5218号车从西方向通过单行道,道上车数: 2 5221号车从西方向进入单行道 5221号车从西方向通过单行道,道上车数: 3 5216号车从西方向离开单行道 5218号车从西方向离开单行道 5221号车从西方向离开单行道 结论分析与体会: 通过这次试验,我了解到了如何利用管程变量来反映进程间的死锁,饥饿。 通过设置信号量来保证每一个进程都有机会来执行,并且运用最基本的goto语句来不断的创建车辆进程,达到要求。 代码: Transport.h: #include #include #include #include #include #include #include #include #include #include #include usingnamespacestd; typedefunionsemuns{ intval; }Sem_uns; enumState{waiting,running}; //哲学家管程中使用的信号量 classSema{ public: Sema(intid); ~Sema(); intdown();//信号量加1 intup();//信号量减1 private: intsem_id;//信号量标识符 }; //哲学家管程中使用的锁 classLock{ public: Lock(Sema*lock); ~Lock(); voidclose_lock(); voidopen_lock(); private: Sema*sema;//锁使用的信号量 }; //哲学家管程中使用的条件变量 classCondition{ public: Condition(Sema*sema1,Sema*sema2); ~Condition(); voidWait(Lock*conditionLock,intdirec);//过路条件不足时阻塞 voidSignal(intdirec);//唤醒相反方向阻塞车辆 private: Sema*sema[2];//一个方向阻塞队列 //Sema*queue2;//另一方向阻塞队列 Lock*lock;//进入管程时获取的锁 }; //哲学家管程的定义 classdp{ public: dp(intrate,intmax); ~dp(); voidArrive(intdirec);//车辆准备上单行道,direc为行车方向 voidCross(intdirec);//车辆正在单行道上 voidLeave(intdirec);//车辆通过了单行道 intgetNum(); voidaddNum(); voiddecNum(); //建立或获取ipc信号量的一组函数的原型说明 intget_ipc_id(char*proc_file,key_tkey); intset_sem(key_tsem_key,intsem_val,intsem_flag); //创建共享内存,放哲学家状态 char*set_shm(key_tshm_key,intshm_num,intshm_flag); private: intrate;//车速 intmaxCars;//最大同向车数 intnumCars;//当前正在通过的车辆数 intcurrentDirec;//当前通过的车辆的方向 Condition*con;//通过单行道的条件变量 Lock*lock;//单行道管程锁 int*buff_ptr; int*put_ptr; Sema*mutex; }; Transport.cc: #include #include #include #include #include #include #include #include #include #include #include usingnamespacestd; typedefunionsemuns{ intval; }Sem_uns; enumState{waiting,running}; //管程中使用的信号量 classSema{ public: Sema(intid); ~Sema(); intdown();//信号量加一 intup();//信号量减一 private: intsem_id;//信号量标识符 }; //单行道管程中使用的锁 classLock{ public: Lock(Sema*lock); ~Lock(); voidclose_lock(); voidopen_lock(); private: Sema*sema;//锁使用的信号量 }; //单行通道管程中使用的条件变量 classCondition{ public: Condition(Sema*semal,Sema*sema2); ~Condition(); voidWait(Lock*conditionLock,intdirec);//过路条件不足时阻塞 voidSignal(intdirec);//唤醒相反方向阻塞的车辆 private: Sema*sema[2];//一个方向阻塞队列 Lock*lock;//进入管程时获取的锁 }; //单行道管程的定义 classdp{ public: dp(intrate,intmax); ~dp(); voidArrive(intdirec);//车辆准备上单行道,direc为单行方向 voidCross(intdirec);//车俩正在单行道上 voidLeave(intdirec);//车辆通过了单行道 intgetNum(); voidaddNum(); voiddecNum(); //建立或获取ipc信号量的一组函数的原型说明 intget_ipc_id(char*proc_file,key_tkey); intset_sem(key_tsem_key,intsem_val,intsem_flag); //创建共享内存,方单行道状态 char*set_shm(key_tshm_key,intshm_num,intshm_flag); private: intrate;//车速 intmaxCars;//最大同向车辆 intnumCars;//当前通过的车辆的数量 intcurrentDirec;//当前通过的车辆的方向 Condition*con;//通过单行道的条件变量 Lock*lock;//单行道管程锁 int*buff_ptr; int*put_ptr; Sema*mutex; }; Sema: : Sema(intid){ sem_id=id; } Sema: : ~Sema(){} intSema: : down() { structsembufbuf; buf.sem_op=-1; buf.sem_num=0; buf.sem_flg=SEM_UNDO; if((semop(sem_id,&buf,1))<0) { perror("downerror"); exit(EXIT_FAILURE); } returnEXIT_SUCCESS; } intSema: : up() { Sem_unsarg; structsembufbuf; buf.sem_op=1; buf.sem_num=0; buf.sem_flg=SEM_UNDO; if((semop(sem_id,&buf,1))<0){ perror("uperror"); exit(EXIT_FAILURE); } returnEXIT_SUCCESS; } Lock: : Lock(Sema*s) { sema=s; } Lock: : ~Lock(){} //上锁 voidLock: : close_lock() { sema->down(); } //开锁 voidLock: : open_lock() { sema->up(); } //用于单行道问题的条件变量 Condition: : Condition(Sema*s0,Sema*s1) { sema[0]=s0; sema[1]=s1; } voidCondition: : Wait(Lock*lock,intdir) { lock->open_lock(); sema[dir]->down(); lock->close_lock(); } voidCondition: : Signal(intdir) { sema[dir]->up(); } intdp: : get_ipc_id(char*proc_file,key_tkey) { #defineBUFSZ256 FILE*pf; inti,j; charline[BUFSZ],colum[BUFSZ]; if((pf=fopen(proc_file,"r"))==NULL) { perror("procfilenotopen"); exit(EXIT_FAILURE); } fgets(line,BUFSZ,pf); while(! feof(pf)) { i=j=0; fgets(line,BUFSZ,pf); while(line[i]=='')i++; while(line[i]! ='')colum[j++]=line[i++]; colum[j]='\0'; if(atoi(colum)! =key)continue; j=0; while(line[i]=='')i++; while(line[i]! ='')colum[j++]=line[i++]; colum[j]='\0'; i=atoi(colum); fclose(pf); returni; } fclose(pf); return-1; } intdp: : set_sem(key_tsem_key,intsem_val,intsem_flg) { intsem_id; Sem_unssem_arg; //测试由sem_key标识的信号量是否已经建立 if((sem_id=get_ipc_id("/proc/sysvipc/sem",sem_key))<0) { //semget新建一个信号灯,其标志号返回到sem_id if((sem_id=semget(sem_key,1,sem_flg))<0) { perror("semaphorecreateerror"); exit(EXIT_FAILURE); } } //设置信号量初值 sem_arg.val=sem_val; if(semctl(sem_id,0,SETVAL,sem_arg)<0) { perror("semaphoreseterror"); exit(EXIT_FAILURE); } returnsem_id; } char*dp: : set_shm(key_tshm_key,intshm_num,intshm_flg) { inti,shm_id; char*shm_buf; //测试由shm_key标识的内存区是否已经建立 if((shm_id=get_ipc_id("/proc/sysvipc/shm",shm_key))<0) { //shmget新建立一个长度为shm_num字节的共享内存 if((shm_id=shmget(shm_key,shm_num,shm_flg))<0) { perror("shareMemoryseterror"); exit(EXIT_FAILURE); } //shmat将由shm_id标识的共享内存附加给指针shm_buf if((shm_buf=(char*)shmat(shm_id,0,0))<(char*)0) { perror("getshareMemoryerror"); exit(EXIT_FAILURE); } for(i=0;i } //共享内存区已经建立,将由shm_id标识的共享内存附加给指针shm_buf if((shm_buf=(char*)shmat(shm_id,0,0))<(char*)0) { perror("getshareMemoryerror"); exit(EXIT_FAILURE); } returnshm_buf; } //单行道行驶问题管程构造函数 dp: : dp(intr,intmax) { intipc_flg=IPC_CREAT|0644; intshm_key=220; intshm_num=5; intsem_key=120; intsem_val=0; intshm_flg=IPC_CREAT|0644; intsem_id; Sema*sema; Sema*sema1; Sema*sema2; rate=r; maxCars=max; 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;//记录是否为第一辆车 buff_ptr[*put_ptr+2]=0;//当前方向超出最大车辆数 buff_ptr[*put_ptr+3]=0;//反方向车辆数 buff_ptr[*put_ptr+4]=0;//记录当前方向 //sum个中同时可以有max个在就餐,建立一个初值为max的用于锁的信号灯 if((sem_id=set_sem(sem_key++,1,ipc_flg))<0) { perror("Semaphorcreateerror"); exit(EXIT_FAILURE); } sema=newSema(sem_id); lock=newLock(sema); //为每一个单行道建立初值为0的用于条件变量的信号灯 if((sem_id=set_sem(sem_key++,sem_val,ipc_flg))<0) { perror("Semaphorcreateerror"); exit(EXIT_FAILURE); } sema=newSema(sem_id); if((sem_id=set_sem(sem_key++,sem_val,ipc_flg))<0) { perror("Semaphorcreateerror"); exit(EXIT_FAILURE); } sema2=newSema(sem_id); con=newCondition(sema1,sema2); //共享内存互斥信号量 sem_id=set_sem(sem_key++,1,ipc_flg); mutex=newSema(sem_id); } //车辆在单行道路口进行判定,是否可以进入 voiddp: : Arrive(intdirec) { intcount; lock->close_lock(); mutex->down(); count=buff_ptr[*put_ptr+1]; mutex->up(); if(count==0) { currentDirec=direc; mutex->down(); buff_ptr[*put_ptr+4]=direc; buff_ptr[*put_ptr+1]=++count; mutex->up(); } stringstr; if(direc==0)str="东"; elsestr="西"; cout< mutex->down(); currentDirec=buff_ptr[*put_ptr+4]; mutex->up(); if(currentDirec! =direc) { mutex->down(); count=buff_ptr[*put_ptr+3]; buff_ptr[*put_ptr+3]=++count; mutex->up(); con->Wait(lock,direc); } sleep (1); lock->open_lock(); } //车辆在单行道阻塞 voiddp: : Cross(intdirec) { intcount,i; lock->close_lock(); for(i=0;i<30;i++) { numCars=getNum(); if(numCars>=maxCars) { mutex->down(); count=buff_ptr[*put_ptr+2]; buff_ptr[*put_ptr+2]=++count; mutex->up(); con->Wait(lock,direc); } } addNum(); stringstr; if(direc==0)str="东"; elsestr="西"; cout< sleep (1); numCars=getNum(); if(direc==0)str="东"; elsestr="西"; cout< "< sleep(rate); lock->open_lock(); } //车辆离开单行道唤醒 voiddp: : Leave(intdirec) { intcount,num; lock->close_lock(); stringstr; if(direc==0)str="东"; elsestr="西"; cout< decNum(); sleep (1); numCars=getNum(); mutex->down(); count=bu
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 死锁 问题 单行道