操作系统学习笔记——哲学家就餐问题

共享数据: data set, Semaphore fork[5] initialized to 1

take_fork(i) : P(fork[i]),  put_fork(i): V(fork[i])

作为哲学家:

指导原则:要么不拿,要么就拿两把叉子

S1 思考中。。。
S2 进入饥饿状态;
S3 如果左邻居或右邻居正在进餐,等待;否则转S4
S4 拿起两把叉子;
S5 吃面条。。。
S6 放下左边的叉子;
S7 放下右边的叉子;
S8 新一轮开始,转S1

作为计算机:

指导原则:不能浪费CPU时间;进程间相互通信

S1 思考中。。。
S2 进入饥饿状态;
S3 如果左邻居或右邻居正在进餐,进程进入阻塞态;否则转S4
S4 拿起两把叉子;
S5 吃面条。。。
S6 放下左边的叉子,看看左邻居现在能否进餐(饥饿状态,两把叉子都在);若能则唤醒之
S7 放下右边的叉子,看看右邻居现在能否进餐(饥饿状态,两把叉子都在);若能则唤醒之;
S8 新一轮开始,转S1

1.必须有数据结构,来描述每个哲学家的当前状态

#define    N        5       哲学家个数
#define   LEFT     (i-1)%N  第i个哲学家的左邻居
#define  RIGHT     (i+1)%N  第i个哲学家的右邻居
#define  THINKING     0     思考状态
#define   HUNGRY    1       饥饿状态
#define  EATING      2      进餐状态
int    state[N];            记录每个人的状态

2.该状态是一个临界资源,各个哲学家对它的访问应该互斥的进行——进程互斥

semaphore mutex;  互斥信号量,初值1

3 一个哲学家吃饱后,可能要唤醒他的左邻右舍,两者之间存在着同步关系——进程同步

semaphore  s[N];    同步信号量,初值0

实现这个过程:

扫描二维码关注公众号,回复: 3072835 查看本文章
void philosopher(int i)   i的取值:0 ~ N-1
{
    while(TRUE)
    {    
        think();            S1 思考中
        take_forks(i);      S2-S4 拿到两把叉子或被阻塞    
        eat();              S5  吃面条中
        put_forks(i);       S6-S7 把两把叉子放回原处
    }
}

函数take_forks ,要么拿到两把叉子,要么被阻塞起来

void take_forks(int i)    i的取值:0~N-1
{
    P(mutex);                        进入临界区,互斥保护HUNGRY状态,和拿两把叉子的操作
    state[i] = HUNGRY;                饿了
    test_take_left_right_forks(i);    试图拿两把叉子
    V(mutex);                        退出临界区
    P(s[i]);                        没有叉子便阻塞
}

void test_take_left_right_forks(int i)  i:0到N-1
{
    if(state[i]) == HUNGRY &&         i:我自己,或其他人
        state[LEFT] != EATING &&
        state[RIGHT] != EATING)
    {
        state[i] = EATING;            拿到两把叉子
        V(s[i]);                       通知第i人可以吃饭了,自己可以吃饭了
    }
}

未完。。。

猜你喜欢

转载自blog.csdn.net/qq_22080999/article/details/82418489