经典IPC问题

经典IPC问题

1.The Dining Philosophers Problem哲学家就餐问题

哲学家的生活中有两种交替活动时段:即吃饭和思考。当一个哲学家觉得饿了时,他就试图分两次去取其左边和右边的叉子,每次拿一把,但不分次序。如果成功地得到了两把叉子,就开始吃饭,吃完后放下叉子继续思考。关键问题是:能为每一个哲学家写一段描述
其行为的程序,且决不会死锁吗?

在这里插入图片描述

#define N 5	//哲学家数目
#define LEFT (i+N-1)%N	//i号哲学家的左边的邻居编号
#define RIGHT (i+1)%N	//i号哲学家的左边的邻居编号
#define THINKING 0
#define HUNGRY 1
#define EATING 2
typedef int semaphore;
int state[N];
semaphore mutex = 1;
semaphore s[N];			//每个哲学家一个信号量

void philosopher(int i)		//哲学家编号:从0到N-1
{
    while(true){	//无限循环
        
    }
}

void take_forks(int i)		//哲学家编号,从0到N-1
{
    //下面的这组down up操作是对test进行保护的
    down(&mutex);
    state[i] = HUNGRY;
    test(i);
    up(&mutex);
    down(&s[i]);		//如果得不到需要的叉子,那么阻塞
}

void put_forks(i)
{
    down(&mutex);
    state[i] = THINKING;		//吃完了,进入思考状态
    test(LEFT);					//提醒左边的哲学家,假如你饿了那么现在可以吃了
    test(RIGHT);				//提醒右边的哲学家,假如你饿了那么现在可以吃了
    up(&mutex);
}

void test(i)
{
    if(state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT] != EATING){
        state[i] = EATING;
        up(&s[i]);
    }
}

2.The Readers and Writers Problem读写者问题

多个读者同时读:可以接受

一个写者在写,读者想读,其他写者想写:都不允许

typedef int semaphore;
semaphore mutex = 1;	//控制对rc的访问
semaphore db = 1;		//控制对数据库的访问
int rc = 0;

void reader(void)
{
    while(TRUE){
        down(&mutex);	//获得对rc的互斥访问
        rc = rc + 1;	//读者数+1
        if(rc == 1)down(&db);	//如果是第一个读者,那么进入写,获得了数据库的访问,那么写者将不再能进入数据库写数据
        //如果此时已经有写者在写了,第一个读者将会阻塞在这里,后续的读者将会阻塞在第9行
        up(&mutex);			//其他的读者就可以进入的
        
        read_data_base();		//访问数据
        
        down(&mutex);			//读者读完再次进入关键区,获得rc的访问权
        rc = rc - 1;			//读者读完,读者数-1
        if(rc == 0)up(&db);		//如果这是最后一个读者,那么唤醒可能阻塞的写者
        up(&mutex);			    //离开对rc的互斥访问
        use_data_read();		//非临界区
    }
}

void writer(void)
{
    while(true){
        think_up_data();	//非临界区
        down(&db);			//写者写的时候任何线程都不能进入
        write_data_base();		//在关键区内进行写操作
        up(&db);			//写完,释放互斥访问
    }
}

​ 这里的rc和数据库访问都是关键区,需要进行互斥访问,所以一旦要对这两个资源进行修改,就要进行相应的down 和 up操作。所以使用一个mutex用来实现对rc的互斥访问,用db来实现对data_base的互斥访问。特别的是,在没有写者时,读者之间对data_base的访问是不需要互斥的。

​ rc的互斥访问比较简单,这里详细说明一下第11行if(rc == 1)down(&db);的作用:这里不仅是让第一个读者进入去,后续的写者没有办法再进入关键区,但后学的第二个第三个由于不满足rc==1而不受影响;更重要的是,这句代码实现了写者访问关键区时,读者将不再能访问关键区——后面假如有读者,第一个读者会被阻塞在第11行的down(&db),而第二个读者,第三个读者将会因为第一个读者无法进行up(&mutex)而阻塞在第9行down(&mutex)。所以11行的代码是理解这个问题的关键。

​ 在上述的程序中允许多个读者一起访问数据库。同时上述的写法也是读者优先的,只要数据库中还有读者在读,就算一个写者在后来的读者前等待,那么后来的读者可以访问数据库,但是写者不行。数据库中存在读者,写者就没有写的机会,假如读者读的时间>到达的时间,比如读者读完要花费5秒,下一个读者以每2s一个的频率到来,那么等待中的写者将永远没有写的机会。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blanche117

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值