操作系统强化

对于信号量的问题,我们具体应该如何处理

常见共五类问题,1.生产者-消费者问题,2.理发师问题,3.读者写者问题,4.哲学家就餐问题

5.单纯的同步问题

1.生产者-消费者问题

六个步骤:

1.判断存在几类进程--每个进程对应一个函数

2.在每个函数内部,使用中文来描述动作(观察是否循环):是一次性动作,还是循环动作

3.分析每一个动作之前,是否需要P什么,只要有P,那么必然存在V,这里还需要对于缓冲区的互斥访问:而且对于缓冲区的PV操作一定要紧贴访问代码

4.PV操作全部写完,随后确定信号量的值

5.检查多个P连续出现的地方,是否会导致死锁:如果发生死锁,那么我们就尝试交换P操作的位置,观察是否还会造成死锁

6.检查是否满足题目要求

定义信号量 semaphore

2.理发师问题

理发师和顾客之间并没有生产和消费关系,而是服务-被服务的关系

int waiting = 0;//正在等待的顾客数量
semaphore mutex = 1; //对于wait的互斥访问
semaphore service = 0; //为了避免顾客没有等待过程,直接进入被服务的代码,需要将这个服务设置为0
semaphore customer = 0; //当顾客到店的话,唤醒服务人员,而没有顾客,服务人员就等待

customer_i(){
    P(mutex);
    if(waiting>=MAX){V(mutex); return;} //如果店内的顾客过多,直接离开,并且需要把锁打开
    取号;
    ++waiting;
    V(mutex);
    V(customer);
    P(service);//等待被叫号
    被服务;
}

server_j(){
    while(1){
        P(mutex);
        if(waiting>0){
            叫号;
            --waiting;
            V(mutex);
            V(service);
            提供服务;
        } else{
            V(mutex);
            P(customer); //如果没有顾客,就等待
        } //else end    
    } //while end
    
}

note:顾客是没有循环的,被服务结束就会离开,但是服务人员是循环的,一直提供服务

 

3.读者写者问题

同类进程不互斥,异类进程互斥

4.哲学家就餐问题

关键在于解除死锁

三种思路:

1. 限制并行(该思路不通用,不建议使用)

单号哲学家先拿左手边筷子,双号哲学家先拿右手边筷子,破坏了请求并保持,这个左右手是哲学家面向桌子的左右手

2.限制并发进程数量(解法2通用,但是并发度不高,不建议使用)

同一时刻仅允许一个哲学家在进行就餐,禁止并行,串行化

3.让进程一口气获得所有资源,然后再开始运行(通用且并发度高)

定义一个mutex确保所有资源是一口气拿下的,拿资源之前先P(mutex),拿完资源之后V(mutex)

如果使用信号量来表示资源,同样存在并发度不高的可能,因为如果获取不到资源就会将进程阻塞

我们改用资源数量(用一个int型的变量来表示资源)

注意:资源数量的定义是使用int类型,而LOCK是semaphore
process(){
    while(1){
        P(LOCK);
        if(资源数量足够){
            获取所有资源;
            对应资源数量减少;
            V(LOCK);
            break;
        }
        V(LOCK);
    }
    进程执行;
    
    P(LOCK);
    资源释放;
    V(LOCK);
}

5.单纯的同步问题

这种问题就是画一个前驱后继图就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值