当前位置首页 > 中学教育 > 初中课件
搜柄,搜必应! 快速导航 | 使用教程  [会员中心]

操作系统死锁问题之单行道问题

文档格式:DOC| 31 页|大小 49.01KB|积分 15|2022-10-07 发布|文档ID:158840734
第1页
下载文档到电脑,查找使用更方便 还剩页未读,继续阅读>>
1 / 31
此文档下载收益归作者所有 下载文档
  • 版权提示
  • 文本预览
  • 常见问题
  • 软件学院操作系统实验报告 实验题目:死锁问题之单行道问题学号:201200301043 日期: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$ ./Transport 7 3 15216号车从西方向等待单行道online@online-Lenovo:~/dxb/test6$ 5217号车从东方向等待单行道down error: Invalid argument5218号车从西方向等待单行道5222号车从东方向等待单行道down error: Invalid argument5221号车从西方向等待单行道5220号车从西方向等待单行道5219号车从东方向等待单行道5216号车从西方向进入单行道down error: Invalid argument5216号车从西方向通过单行道,道上车数:15218号车从西方向进入单行道5218号车从西方向通过单行道,道上车数:25221号车从西方向进入单行道5221号车从西方向通过单行道,道上车数:35216号车从西方向离开单行道5218号车从西方向离开单行道5221号车从西方向离开单行道结论分析与体会: 通过这次试验,我了解到了如何利用管程变量来反映进程间的死锁,饥饿。

    通过设置信号量来保证每一个进程都有机会来执行,并且运用最基本的goto语句来不断的创建车辆进程,达到要求 代码:Transport.h:#include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef union semuns { int val;} Sem_uns; enum State {waiting, running}; //哲学家管程中使用的信号量class Sema{public: Sema(int id); ~Sema(); int down(); //信号量加 1 int up(); //信号量减 1private: int sem_id; //信号量标识符};//哲学家管程中使用的锁class Lock{public: Lock(Sema *lock); ~Lock(); void close_lock(); void open_lock();private: Sema *sema; //锁使用的信号量};//哲学家管程中使用的条件变量class Condition {public: Condition(Sema *sema1 , Sema *sema2); ~Condition(); void Wait(Lock *conditionLock,int direc); //过路条件不足时阻塞 void Signal( int direc); //唤醒相反方向阻塞车辆private: Sema* sema[2]; // 一个方向阻塞队列// Sema* queue2; // 另一方向阻塞队列 Lock* lock; // 进入管程时获取的锁}; //哲学家管程的定义class dp{public: dp(int rate, int max); ~dp(); void Arrive(int 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_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;};Transport.cc:#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;typedef union semuns{int val;}Sem_uns;enum State {waiting,running};//管程中使用的信号量class Sema{public: Sema(int id); ~Sema(); int down();//信号量加一 int up();//信号量减一private: int sem_id;//信号量标识符};//单行道管程中使用的锁class Lock{public: Lock(Sema * lock); ~Lock(); void close_lock(); void open_lock();private: Sema * sema;//锁使用的信号量};//单行通道管程中使用的条件变量class Condition{public: Condition(Sema * semal,Sema * sema2); ~Condition(); void Wait(Lock * conditionLock,int direc);//过路条件不足时阻塞 void Signal(int direc);//唤醒相反方向阻塞的车辆private: Sema * sema[2];//一个方向阻塞队列 Lock * lock;//进入管程时获取的锁};//单行道管程的定义class dp{public: dp(int rate,int max); ~dp(); void Arrive(int 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_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;};Sema::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(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))<0){perror("up error");exit(EXIT_FAILURE);}return EXIT_SUCCESS;}Lock::Lock(Sema * s){sema=s;}Lock::~Lock(){}//上锁void Lock::close_lock(){sema->down();}//开锁void Lock::open_lock(){sema->up();}//用于单行道问题的条件变量Condition::Condition(Sema * s0,Sema * s1){sema[0]=s0;sema[1]=s1;}void Condition::Wait(Lock * lock,int dir){lock->open_lock();sema[dir]->down();lock->close_lock();}void Condition::Signal(int dir){sema[dir]->up();}int dp::get_ipc_id (char * proc_file,key_t key){#define BUFSZ 256 FILE * pf; int i,j; char line[BUFSZ],colum[BUFSZ]; if((pf=fopen(proc_file,"r"))==NULL) { perror("proc file not open"); 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); 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_FAILURE);}}//设置信号量初值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){//shmget 新建立一个长度为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;iclose_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();}string str;if(direc==0) str="东";else str="西";cout<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();}//车辆在单行道阻塞void dp::Cross(int direc){int count,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();string str;if(direc==0) str="东";else str="西";cout<open_lock();}//车辆离开单行道唤醒void dp::Leave(int direc){int count,num;lock->close_lock();string str;if(direc==0)str="东";else str="西";cout<down();count=buff_ptr[*put_ptr+3];num=buff_ptr[*put_ptr+2];mutex->up();if(numCars==0&&count!=0){while(count--){con->Signal(1-direc);}mutex->down();buff_ptr[*put_ptr+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){while(num--){con->Signal(direc);}mutex->down();buff_ptr[*put_ptr+2]=0;buff_ptr[*put_ptr]=0;mutex->up();}lock->open_lock();}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();}//单行道问题并发执行入口int main(int argc,char * argv[]){dp * tdp;//单行道管程对象的指针int cars;int dir;int pid;int max=2;int rate=3;rate =(argc>3)?atoi(argv[3]):3;//速度cars=(argc>1)?atoi(argv[1]):5;//总共的车辆数目max=(argc>2)?atoi(argv[2]):2;//每条道上最大的数目tdp=new dp(rate,max);//建立一个单行道的管程对象start: if((pid=fork())==0) { srand(getpid()); dir=rand()%2; tdp->Arrive(dir); tdp->Cross(dir); tdp->Leave(dir); } else { if(--cars) { goto start; } } return 0;}Makefile:head = Transport.hsrcs = Transport.ccobjs = Transport.oopts = -w -g -call: TransportTransport: $(objs) g++ $(objs) -o TransportTransport.o: $(srcs) $(head) g++ $(opts) $(srcs)clean: rm Transport *.o。

    点击阅读更多内容
    卖家[上传人]:chenhao
    资质:实名认证