7.4 Highest Locker Protocol/Pattern
Bruce Powel Douglass大师介绍-CSDN博客https://blog.csdn.net/ChatCoding/article/details/134665868嵌入式软件开发从小工到专家-CSDN博客https://blog.csdn.net/ChatCoding/article/details/135297955C嵌入式编程设计模式源码-CSDN博客https://blog.csdn.net/ChatCoding/article/details/134819019最高锁定模式虽然可以减少优先级反转的情况但并不能保证完全避免死锁。其他模式如有序锁定模式Ordered Locking Pattern和同时锁定模式Simultaneous Locking Pattern则提供了避免死锁的其他方法。7.4.1 抽象最高锁定模式是解决无界阻塞/无界优先级反转问题的另一种解决方案。最高锁定模式为每个资源定义了一个优先级上限。在最高锁定模式下如果任务没有阻塞任何更高优先级的任务则其优先级不会提升。只有当任务阻塞了一个或多个更高优先级的任务时任务的优先级才会提升到其所持有资源中最高的优先级。HLPHighest Locker Protocol:一步到位:HLP 会直接将任务的优先级提升到资源的上限优先级。快速响应:HLP 可以快速响应高优先级任务的资源请求避免高优先级任务长时间阻塞。PIPPriority Inheritance Protocol:逐步提升:PIP 会逐步提升任务的优先级每当被阻塞任务的优先级高于当前优先级则提升一次持有资源任务的优先级。响应速度慢:PIP 的响应速度相对较慢因为需要多次提升才能达到最终的优先级。这限制了优先级反转任务的优先级只能提升到其所持有的资源的最高优先级因此因资源竞争而导致的优先级反转最多发生一次。它与优先级继承模式不同任务在拥有资源时被更高优先级的任务抢占这个更高优先级的任务不需要当前已被锁定的资源不会发生链式阻塞。在最高锁定模式Highest Locker Pattern中当一个任务在拥有资源时被抢占不会发生链式阻塞因为如果它需要这个资源它的优先级就不会比资源的优先级上限还高所以它无法抢占。因此就不会有一个任务在等待另一个任务释放资源时被阻塞进而导致链式阻塞。只要任务在拥有资源时不自行挂起这种设计避免了任务在拥有资源时被抢占导致的链式阻塞。任务在拥有资源时主动挂起自己可能会出现链式阻塞类似于优先级继承模式Priority Inheritance Pattern因此可能会出现死锁情况。任务在拥有资源时主动挂起可能会导致链式阻塞因为这种行为可能违反了最高锁定模式的规则。在最高锁定模式中任务在获取资源时会提升到该资源的优先级上限以此来限制优先级反转。然而如果任务在持有资源的同时挂起自己它就无法释放资源如果有其他任务需要这些被挂起任务持有的资源它们也会被阻塞。如果这些被阻塞的任务又持有其他资源那么又会有更多的任务因为等待这些资源而被阻塞从而形成一条阻塞链。这种链式阻塞可能会涉及多个任务和资源最终可能导致系统的运行效率降低甚至出现死锁的情况。为了避免死锁应该确保任务在拥有资源时不会挂起自己。如果系统允许任务在拥有资源时挂起自己那么就需要像处理优先级继承模式那样计算最坏情况下的阻塞时间遍历链式阻塞的最长情况。只要拥有资源的任务不将自己挂起就不会出现死锁的情况。为了避免死锁需要打破死锁的四个必要条件中的至少一个。最高锁定模式主要是通过限制优先级反转来解决无界阻塞/无界优先级反转问题但它并没有直接解决死锁问题。相比之下优先级上限模式Priority Ceiling Pattern旨在限制最大优先级反转到单一级别并完全防止基于资源的死锁。7.4.2 问题解决资源竞争而导致的无限优先级反转。7.4.3 模式结构图 7-10最高锁定模式最高锁定模式的结构元素与优先级继承模式类似如图 7-10 所示。唯一的区别在于共享资源新增了名为priorityCeiling的属性。该模式通过为每个可锁定资源定义一个上限优先级priorityCeiling。priorityCeiling仅比资源最高优先级客户端的优先级稍高一级并在设计时确定。当资源被锁定时锁定任务的优先级会提升到该资源的上限优先级。7.4.4 协作角色抽象线程 (Abstract Thread)抽象类不可直接实例化。与调度器关联保证接口一致性。抽象线程是一个“活动”对象意味着它创建时会创建一个线程用于运行。它通过组合关系包含一些被动对象这些被动对象在“活动”对象的线程中执行。具体线程 (Concrete Thread)可实例化的抽象线程子类。用于包含执行系统实际工作的“语义对象”。提供将这些语义对象纳入并发架构的直接方式。互斥锁 (Mutex)互斥锁是一个互斥信号量对象一次只允许一个调用者通过。共享资源的操作每当调用相关服务时都会调用它在启动服务之前将其锁定并在服务完成后将其解锁。一次只允许一个调用者通过互斥信号量访问共享资源。共享资源的服务调用会锁定它完成后解锁。尝试调用已锁定的资源则会被阻塞直到互斥锁解锁。互斥信号量向调度器发送信号通知调度器当前活动线程尝试调用互斥信号量并提供互斥信号量 ID 用于以后释放时解锁和入口点线程继续执行的位置。调度器 (Scheduler)调度器根据线程优先级协调多个线程的执行始终运行就绪队列中具有最高优先级的任务。当“活动”线程对象创建时它会调用createThread操作为其创建一个任务。当任务未被阻塞或抢占调度器会调用StartAddr地址从头开始执行此任务当任务已被阻塞或抢占调度器则会调用EntryPoint地址继续执行此任务。在最高锁定模式中当互斥锁试图访问已被锁定的资源时调度器会阻塞请求任务将其放入阻塞队列中。将拥有资源的任务的优先级提升到共享资源的priorityCeiling。共享资源 (Shared Resource)共享资源是多个线程共享的对象。为了保证系统正常运行所有共享资源要么是可重入的要么必须受到保护。当线程尝试使用受保护的资源时会检查资源关联的互斥锁。如果被锁定则将任务放入阻塞队列并将其重新进入点记录在 TCB 中。共享资源有一个名为priorityCeiling的常量属性其值要比能访问该资源的最高优先级的任务的优先级要高一级这确保了当资源被锁定时使用该资源的其他任务不能抢占它。任务控制块 (Task Control Block, TCB)TCB包含与其对应的线程对象相关的调度信息包括线程的优先级、默认启动地址以及在完成之前被抢占或阻塞时的入口地址。调度器为每个现有线程维护一个 TCB 对象。TCB 记录线程的当前优先级可能因资源访问和阻塞而提升及其初始默认优先级。