哲学家的PV操作(自己想出来的实现方法)

        这个思想是我自己想出来的,一开始的第一位哲学家肯定能同时拿到两个筷子,后面的相邻哲学家只能最多拿到1个筷子,不需要其他的限制(比如奇数偶数位哲学家偶数),同时满足:空闲让进;忙则等待;有限等待;让权等待;

        这个想法不确定是否和别人的雷同,但我确实是自己想出来的;因为本人能力问题,如有错误,请帮忙指出;谢谢!

 思想是这样的:

        1.设置一个mutex 互斥量,用来互斥的拿起筷子(已经被使用used,可以使用usable)和修改哲学家的状态(thinking,eating,waiting(多种,看代码));

        2.当哲学家从thinking 到eating的过程中,有以下几种情况:
             (1)左右筷子都可以用,把左右筷子设置使用态,那么直接把自己的状态设置为eating

             (2)左筷子或者右筷子不可以用时,分别修改右左筷子状态(相当于拿起筷子),把自己设置等待态;分别对应等左和等右;这时他们只需要等一位哲学家就可以了,所以一个P等待

             (3)左和右筷子都已经被使用了这时需要等左右两个哲学家,两个P等待

        3.当哲学家吃饭完,首先把自己改为思考态,同时释放左右筷子,回到思考状态时,有以下几种情况:

              (1)当左边的哲学家在等自己时,说明自己的左筷子需要让出来,所以把左筷子设置为使用态,同时唤醒(通知一下)左哲学家;若果此时左哲学家只在等右筷子,所以马上就能被唤醒;若果是在等左右筷子,那么唤醒后运行一个P操作后(等左右筷子是两个P操作),再被阻塞而让出CPU;

              (2)当右边的哲学家在等自己时,说明自己的右筷子需要让出来,所以把右筷子设置为使用态,同时唤醒(通知一下)右哲学家;若果此时右哲学家只在等左筷子,所以马上就能被唤醒;若果是在等左右筷子,那么唤醒后运行一个P操作后(等左右筷子是两个P操作),再被阻塞而让出CPU;

semophore mutex=1 //互斥访问筷子和修改哲学家的状态
semophore mupho[5]={0} //哲学家的通信信号
#define thinking 0 //可以思考了
#define eating   1 //可以吃饭了
#define waitl    2 //等待左边left的筷子
#define waitr    3 //等待右边right的筷子
#define waitlr   4 //等待两边的筷子
#define used     0
#define usable   1

int pho[5]={thinking ,thinking ,thinking ,thinking ,thinking}
int stick[5]={usable,usable, usable,usable,usable}

philosopher(int i) //i 对应第几个哲学家 0,1,2,3,4
{
    While(1)
(
    思考

    P(mutex);    //互斥访问筷子和哲学家修改状态 
    If(stick[i%5]=usable and stick[(i+1)%5]=usable) //左右筷子都可以用,都拿上
    { 
        stick[(i)%5]=used;
        stick[(i+1)%5]=used;
    }
    Else if(stick[(i)%5]=used and stick[(i+1)%5]=usable)//左筷子已经被用了
    {
        tick[(i+1)%5]=used; //拿起右筷子
        pho[i]=waitl;       //等左筷子
    } 
    Else if(stick[(i)%5]=usable and stick[(i+1)%5]=used)//右筷子已经被用了
    {
        tick[(i)%5]=used; //拿起左筷子
        pho[i]=waitr;     //等右筷子  
    } 
    Else pho[i]=waitlr;  //左右筷子都已经被用
    V(mutex);   //互斥访问筷子和哲学家修改状态

    If(pho[i]=waitl or pho[i]=waitr) //左或者右筷子被占用,就等一个P操作
        P(mupho[i]);
    Else if(pho[i]=waitlr); //左和右筷子被占用,就等二个P操作
        P(mupho[i]);
        P(mupho[i]);

    P(mutex);
    pho[i]=eating;
    V(mutex);

    吃饭

    P(mutex)  //互斥访问筷子和哲学家修改状态
    Pho[i]=thinking;      //改为思考状态
    stick[(i)%5]=usable;  //释放左筷子
    stick[(i+1)%5]=usable;//释放右筷子
    if(pho[(i-1)%5]=waitr. Or. pho[(i-1)%5]=waitlr)  //当前哲学家的左边哲学家在等它的右边筷 
       stick[(i)%5]=used                             //子,所以把当前哲学家的左边筷子交给
       V(mupho[(i-1))%5])                            //左边哲学家,把筷子设使用态,并且V操
                                                     //作
    if (pho[(i+1))%5]=waitl. Or. pho[(i+1)%5]=waitlr) //当前哲学家的右边哲学家....
        Stick[(i+1)%5]=uesd
       V(mupho[(i+1)%5])
    V(mutex) //互斥访问筷子和哲学家修改状态

}

### 哲学家就餐问题的PV操作实现 哲学家就餐问题是计算机科学中经典的同步问题之一,用于描述多个线程或进程之间的竞争条件以及如何通过信号量机制解决这些问题。以下是基于PV操作的具体解决方案。 #### 1. 使用信号量控制筷子资源 为了防止死锁并确保互斥访问筷子资源,可以通过定义一组二值信号量来表示每根筷子的状态。初始状态下,所有的筷子都是可用的,因此这些信号量都被初始化为1[^1]。 ```java semaphore chopstick[5] = {1, 1, 1, 1, 1}; ``` #### 2. 控制同时进餐的哲学家人数 为了避免死锁的发生,可以采用一种简单的策略:限制同时尝试进餐的哲学家数量不超过4位。这可以通过引入另一个计数型信号量`count`来实现,其初值设置为4[^3]。 ```java semaphore count = 4; ``` #### 3. 哲学家的行为逻辑 每位哲学家的行为可以用一个循环结构模拟,其中交替执行思考和进餐两个阶段。具体来说: - **思考阶段**:无需任何特殊处理。 - **进餐阶段**: - 首先等待`count`信号量以获得进入餐厅的权利; - 接下来分别获取左右手边的筷子(即调用两次`wait()`函数); - 进食完成后释放两根筷子,并通知其他哲学家自己已经离开餐桌(即调用两次`signal()`函数),最后还应增加`count`以便更多哲学家有机会进餐。 下面是完整的伪代码版本: ```c void philosopher(int i) { while (true) { think(); // 思考 wait(count); // 请求进入房间进餐 wait(chopstick[i]); // 获取左边筷子 wait(chopstick[(i + 1) % 5]);// 获取右边筷子 eat(); // 吃饭 signal(chopstick[i]); // 放下左边筷子 signal(chopstick[(i + 1) % 5]);// 放下右边筷子 signal(count); // 离开房间 } } ``` 以上方法有效解决了哲学家就餐过程中的潜在死锁风险,同时也保证了系统的公平性和效率。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值