2021年11月22日 *** 作系统(信号量解决一些问题+死锁)

2021年11月22日  *** 作系统(信号量解决一些问题+死锁),第1张

2021年11月22日 *** 作系统(信号量解决一些问题+死锁) 1. 生产者消费者问题

 

 

 

1.1 总结

 

2. 多生产者-多消费者问题

 

 

 

 

 

2.1 总结

 

3. 吸烟者问题 

 

 

 

 3.1 总结

4. 读者-写者问题 

 

 

 

 

 

5. 哲学家进餐问题

可能产生死锁现象 

防止死锁发生

 

第三种方法的缺点

 

 可能存在一个进程需要的两个临界资源可用但拿不到然后被阻塞,也可能一个进程只拿到一个临界资源然后被阻塞

 

 

 

5. 管程

 

 5.1 为什么要引入管程

 

5.2 管程的定义和基本特征

5.3 管程解决生产者和消费者问题 

 

 

5.4 Java中类似于管程的机制

 

5.5 总结

 

6. 死锁的概念

 

 

6.1 死锁、饥饿、死循环 

6.2 死锁产生的必要条件 

6.3 什么时候会发生死锁 

6.4 死锁的处理策略 

6.5 总结 

 

7. 预防死锁

 7.1 破坏互斥条件

 

7.2 破坏不可剥夺条件

 

7.3 破坏请求和保持条件

7.4 破坏循环等待条件 

进程在已经申请到大编号的临界资源后不能再去申请小编号的临界资源,打破了进程申请资源循环死锁链

 

7.5 总结

 

8. 避免死锁

8.1 安全序列  

 

 

 

 实际计算可以更加简便的使用银行家算法

 

 

 

 

 9. 死锁的检测和解除

 

9.1 死锁的检测

 

 

9.2 死锁的解除    9.3 总结

 

总结

1.聊聊你知道的信号量机制应用到的同步问题?

生产者消费者问题

//互斥要贴在对临界资源的访问,不然会产生死锁
//生产者消费者不涉及对临界资源的 *** 作的代码段写在PV *** 作之外,这样提高进程的并发度

semaphore mutex = 1;
semaphore empty = n;
semaphore full = 0;

public void Producer(){
    while(1)
    {
        生产一个产品;
    	P(empty);
    	P(mutex);
    	将产品放入缓冲区;
    	V(mutex);
    	V(full);      
    }   
}

public void Consumer(){
    while(1)
    {
        P(full);
    	P(mutex);
    	将产品从缓冲区拿出;
    	V(mutex);
    	V(empty);
    	消费一个产品;   
    }
}

多生产者多消费者问题

// 这里不设置互斥信号量mutex的原因是临界资源的大小为1,因此不会产生两个及以上的进程访问临界资源
// 注意这里semaphore类型变量只设置一个Plate,因为儿子和女儿在访问完临界资源后,父亲和母亲都可以开始生产。

semaphore apple = 0;
semaphore banana = 0;
semaphore plate = 1;

public void Dad(){
    while(1){
        削苹果;
        P(plate);
    	将苹果放入盘子;
    	V(apple);
    }   
}

public void Mom(){
    while(1){
    	剥香蕉;
    	P(plate);
    	将香蕉放入盘子;
    	V(banana);
    }
}

public void Son(){
    while(1){
    	P(apple);
    	从盘子拿出苹果;
    	V(plate);
    	吃苹果
    }
}

public void daughter(){
    while(1){
    	P(banana);
   		从盘子拿出香蕉;
    	V(plate);
        吃香蕉;
    }
}

吸烟者问题

semaphore offer1 = 0;
semaphore offer2 = 0;
semaphore offer3 = 0;
semaphore ashtray = 1;
int i = 0;

public void offer(){
    if(i == 0){
        生产offer1;
        P(ashtray);
        将offer1放入烟灰缸;
        V(offer1);
    }
    else if(i == 1){
        生产offer2;
        P(ashtray);
        将offer2放入烟灰缸;
        V(offer2);
    }
    else if(i == 2){
        生产offer3;
        P(ashtray);
        将offer3放入烟灰缸;
        V(offer3);
    }
    
    i = (i+1)%3;    
}

public void smoker1(){
    P(offer1);
    从烟灰缸拿出offer1;
    V(ashtray);
    使用offer1;
}

public void smoker2(){
    P(offer2);
    从烟灰缸拿出offer2;
    V(ashtray);
    使用offer2;
}

public void smoker3(){
    P(offer3);
    从烟灰缸拿出offer3;
    V(ashtray);
    使用offer3;
}

2.聊聊你知道的死锁?死锁、线程饥饿以及死循环的区别?

  死锁可能发生的条件有:资源分配给各个进程不当、信号量使用不当互斥 *** 作在同步 *** 作之前以及进程申请资源的顺序之间有冲突等。死锁产生的条件必须满足四点:1.申请资源互斥(通过spolling技术解决,使得互斥资源虚拟不互斥)。2.循环等待(打破循环等待链,使最多能申请资源的进程小于N-1等)。3.不可剥夺条件(优先级高的可以强行剥夺运行中优先级低的进程,这样会导致优先级低的进程饥饿一直不能执行完毕,并且让正在执行的被剥夺临界资源的进程的进度前功尽弃)。4.请求和保持条件(在进程上处理机进入运行状态之前申请好所有需要的临界资源,这样做会导致系统并发度降低。),破坏上述条件任意一条就可以静态预防死锁。动态避免死锁:通过银行家算法假设把临界资源分配给部分资源看是否会让系统的序列进入不安全状态来决定是否分配这次临界资源。解除死锁:通过临界资源-->进程的分配边以及进程-->临界资源的请求边是否可完全简化来检测死锁。(优先让进程优先级低、申请到的临界资源少、运行时间短、从被加入到就绪队列到当前时间的时间小的进程让出临界资源去简化。)。解除死锁的方法有剥夺资源法(将被剥夺的资源挂起到外存,可能会导致被挂起进程的饥饿。)、进程撤销法(强制撤销部分或者全部进程,可能会导致有的进程快要结束但是被撤销,前功尽弃)、进程回退法(使部分进程回退到足以避免死锁的状态,需要设置一系列进程实体的还原点)

  死锁发生在两个进程之间,是由 *** 作系统分配给进程临界资源的顺序不当等造成的,它只可能发生在阻塞态。线程饥饿是发生在单个进程,是单个进程一直不能运行完成而产生的问题,它既可能发生在得不到处理机和所需资源的阻塞态也可能发生在得不到处理机的就绪态。死循环或者是程序员编辑代码有问题或者是有意使用该循环。死锁、线程饥饿发生在 *** 作系统对进程的处理(管理者级别),而死锁发生在被 *** 作系统管理的进程(被管理者级别)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5574247.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存