操作系统——2.4 (管程与死锁的基本概念)
一、管程——高级同步机制
这里和Java面向对象的语言 ——“函数”,“封装”,“类”的思想很像。O(∩_∩)O
总结来看,
管程是指一种控制并发访问共享资源的机制,它由共享数据、对数据操作的方法及一组同步机制组成。其中关键的部分包括共享数据结构、对数据的访问方法和使用的同步机制。
举个生活中的例子来理解管程,可以想象一个图书馆管理系统。这个系统中包含了共享的图书资源(共享数据)、借书和还书的操作(对数据的访问方法)以及限制同时借书的人数等同步机制。图书馆系统需要确保数据的一致性和安全性,避免出现多个人同时对同一本书进行操作的情况。
在Java中,类是一种定义对象的模板,封装是指将数据和操作数据的方法封装到一个类中,从而实现数据的隐藏和保护,避免外部直接访问和修改数据。函数则是实现特定功能的代码块,可以接受输入参数并返回结果。
举例来说,一个学生类可以包含学生的姓名、学号等数据以及获取姓名和学号的方法。在类的封装下,外部只能通过类提供的方法来获取和设置数据,而不能直接修改数据。函数则可以是计算两个数的和或差的代码块,通过输入参数得到结果并返回。通过类、封装和函数的组合,可以更好地组织和管理代码,实现更好的代码复用和可维护性。
【补充知识点】
特性 | 条件变量(没有值) | 信号量(有值) |
---|---|---|
定义 | 用于线程之间的同步和通信,用于线程等待特定条件发生或通知其他线程某个条件已满足 | 用于管理对共享资源的访问和同步,用于控制并发访问共享资源的数量,并防止竞争条件产生 |
操作 | 等待(x.wait)、信号(x.signal) 通知(notify)、广播(broadcast) | 信号(signal)、等待(wait)、PV操作(P操作和V操作) |
等待操作 | 在等待条件变量的信号前,线程会被阻塞 | 在等待信号量的资源前,线程会被阻塞 |
通知操作 | 通知一个等待在条件变量上的线程,使其解除阻塞 | 发送信号给等待在信号量上的线程,使其解除阻塞 |
适用场景 | 适用于需要线程根据特定条件进行等待和唤醒的场景 | 适用于控制并发访问共享资源的数量,防止竞争条件产生的场景 |
并发性 | 高并发环境下效率较高,可以更精确地控制线程的等待和唤醒操作 | 在控制并发访问共享资源的数量上表现更为出色,但在复杂条件下缺乏精细的控制 |
应用示例 | 多线程生产者消费者模型中使用条件变量等待队列为空或满 | 控制线程数目、实现互斥访问共享资源时使用信号量 |
二、死锁
思考?—— 之前的哲学家进餐问题中就有死锁现象的发生。
五个哲学家都拿了一根筷子,都在等待自己旁边的哲学家放下筷子,啊,饭都凉了,他们谁也不让谁,都吃不了饭,陷入了无尽的等待。 用官方的话说,即五个哲学家进程都不能向下推进,发生阻塞,就会陷入“死锁”状态。
PPT上的例子如下,你我他她不知道谁是谁,本人懵懵的,有缕清关系的写在评论区,大大的感谢(* ̄︶ ̄)
死锁、饥饿、死循环的区别:
死锁产生的必要条件:
死锁产生的原因:
死锁的处理策略:
下一章详细介绍这三种处理策略,脑容量不够了。