:本文记录 WHUT-计算机学院-操作系统 课程 实验2:进程管理

纸上得来终觉浅,觉知此事需躬行!

 

1、实验内容:

实验预备:掌握进程管理的相关内容,对进程的同步和互斥,及信号量机制有深入的理解

实验内容:模拟实现用信号量机制解决哲学家就餐问题  (或其他经典的同步问题)

具体要求:

  • 任选一种计算机高级语言编程实现
  • 实现5个哲学家(5只筷子)的顺利就餐
  • 需避免出现死锁
  • 使用信号量、及信号量的等待队列
  • 使用P操作、V操作
  • 能够显示每个哲学家、及每只筷子的状态   

 

2、运行截图:

【操作系统】实验2:进程管理_武汉理工

 

3、源代码:
package test2;

/*每个哲学家安排一个线程*/
class Philosopher extends Thread{
    private String name;
    private Chopsticks Chopsticks;
    public Philosopher(String name,Chopsticks Chopsticks){
        super(name);
        this.name=name;
        this.Chopsticks=Chopsticks;
    }

    //重构
    public void run(){
        while(true){
        	//哲学家的状态就是:思考→进餐→思考  循环
            thinking();
            Chopsticks.P();
            eating();
            Chopsticks.V();
        }
    }
    
    public void eating(){
    	int i = Integer.parseInt(name);
        System.out.println("哲学家 " + name + "号 开始拿着筷子 "+ i +" 和 "+ (i+1)%5 + "进餐!");//打印哲学家状态和筷子状态
        try {
            sleep(2000);//假设吃饭时间为5秒钟
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
   
    public void thinking(){
        System.out.println("哲学家 " + name + "号 陷入了思考!");
        try {
            sleep(2000);//假设思考4秒钟
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


class Chopsticks{
    /*5只筷子,初始为1,即未被用*/
    private int[] ChopStatus={1,1,1,1,1};

    //避免死锁
    /*P操作:只有当左右手的筷子都未被使用时,才允许获取筷子,且必须同时获取左右手筷子*/
    public synchronized void P(){
    	//获得当前线程的名字(哲学家)
        String name = Thread.currentThread().getName();
        int i = Integer.parseInt(name);
        
        //当当前线程哲学家左右手的筷子已经被占用
        while(ChopStatus[i]==0||ChopStatus[(i+1)%5]==0){
            try {
            	System.out.println("哲学家 "+ name +"号 正在等待筷子!");
                //当前哲学家线程进入等待状态         
            	wait();  
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        //获得左右筷子,修改筷子状态
        ChopStatus[i]-=1 ;
        ChopStatus[(i+1)%5]-=1;
    }

    
    /*V操作:同时释放左右手的筷子*/
    public synchronized void V(){
    	//获得当前线程的名字(哲学家)
        String name = Thread.currentThread().getName();
        int i = Integer.parseInt(name);

        //释放左右筷子
        ChopStatus[i]+=1;
        ChopStatus[(i+1)%5]+=1;
        
        //唤醒等待序列中的线程
        notifyAll();
    }
}


public class Think_Eat {
    public static void main(String []args){
    	
        Chopsticks Chopsticks = new Chopsticks();
        new Philosopher("0",Chopsticks).start();
        new Philosopher("1",Chopsticks).start();
        new Philosopher("2",Chopsticks).start();
        new Philosopher("3",Chopsticks).start();
        new Philosopher("4",Chopsticks).start();
        
    }
}