博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[JAVA学习笔记-72]关于Priority Inversion
阅读量:4099 次
发布时间:2019-05-25

本文共 4111 字,大约阅读时间需要 13 分钟。

任务优先级倒转。在任务设计时,如果分配了优先级,则高优先级的任务应该能够正常抢占低优先级任务的CPU时间和资源(mutex保护的资源),并先于

低优先级任务执行。

实际使用mutex(或其它类似于Object锁)的机制时,低优先级任务若持有锁,会导致高优先级的任务在获取锁时阻塞,如果低优先级任务恰巧
没有及时释放锁,将可能导致严重问题。例如,高优先级任务可能会有超时定时器保护,一旦被阻塞过久会触发定时器,可能造成系统被重置。
上述的场景,即,没有遵循高优先级任务优先执行的原则,即所谓优先级倒置。

解决方案(wikipedia):

Solutions[edit]

The existence of this problem has been known since the 1970s. Lampson and Redell [3] published one of the first papers to point out the priority inversion problem. Systems such as the UNIX kernel were already addressing the problem with the splx() primitive. There is no foolproof method to predict the situation. There are however many existing solutions, of which the most common ones are:

1、Disabling all interrupts to protect critical sections

When disabling interrupts are used to prevent priority inversion, there are only two priorities: preemptible, and interrupts disabled. With no third priority, inversion is impossible. Since there’s only one piece of lock data (the interrupt-enable bit), misordering locking is impossible, and so deadlocks cannot occur. Since the critical regions always run to completion, hangs do not occur. Note that this only works if all interrupts are disabled. If only a particular hardware device’s interrupt is disabled, priority inversion is reintroduced by the hardware’s prioritization of interrupts. In early versions of UNIX, a series of primitives named splx(0) … splx(7) disabled all interrupts up through the given priority. By properly choosing the highest priority of any interrupt that ever entered the critical section, the priority inversion problem could be solved without locking out all of the interrupts. Ceilings were assigned in rate-monotonic order, i.e. the slower devices had lower priorities.
In multiple CPU systems, a simple variation, “single shared-flag locking” is used. This scheme provides a single flag in shared memory that is used by all CPUs to lock all inter-processor critical sections with a busy-wait. Interprocessor communications are expensive and slow on most multiple CPU systems. Therefore, most such systems are designed to minimize shared resources. As a result, this scheme actually works well on many practical systems. These methods are widely used in simple embedded systems, where they are prized for their reliability, simplicity and low resource use. These schemes also require clever programming to keep the critical sections very brief. Many software engineers consider them impractical in general-purpose computers.

2、A priority ceiling

With priority ceilings, the shared mutex process (that runs the operating system code) has a characteristic (high) priority of its own, which is assigned to the task locking the mutex. This works well, provided the other high priority task(s) that tries to access the mutex does not have a priority higher than the ceiling priority.

3、Priority inheritance

Under the policy of priority inheritance, whenever a high priority task has to wait for some resource shared with an executing low priority task, the low priority task is temporarily assigned the priority of the highest waiting priority task for the duration of its own use of the shared resource, thus keeping medium priority tasks from pre-empting the (originally) low priority task, and thereby affecting the waiting high priority task as well. Once the resource is released, the low priority task continues at its original priority level.
【根据StackOverflow的信息,Linux内核使用的是pthread包的接口,可以指定锁的处理遵循 Priority inheritance Protocol。
这种方案我认为是一种折中解决方案,当低优先级任务持有锁及锁保护的资源时,临时将等待队列中最高优先级任务的优先级赋给持有锁的低优先级任务,此时该任务即临时具有最高优先级,这样就维持了高优先级任务优先执行的原则,当任务释放资源,则恢复原来的低优先级,此时则确保它可以继续被
抢占。

4、Random boosting

Ready tasks holding locks are randomly boosted in priority until they exit the critical section. This solution is used in Microsoft Windows.【Windows给我的感觉是一直没有采用最先进的方案,因此Windows的机制暂时不作深入研究】

5、Avoid blocking

Because priority inversion involves a low-priority task blocking a high-priority task, one way to avoid priority inversion is to avoid blocking, for example by using Non-blocking synchronization or Read-copy-update.
【完全放弃阻塞方式是不现实的,毕竟这是最简便好用的同步方案】

转载地址:http://vphii.baihongyu.com/

你可能感兴趣的文章
Java并发编程1-线程池
查看>>
CentOS7,玩转samba服务,基于身份验证的共享
查看>>
计算机网络-网络协议模型
查看>>
计算机网络-OSI各层概述
查看>>
Java--String/StringBuffer/StringBuilder区别
查看>>
mySQL--深入理解事务隔离级别
查看>>
分布式之redis复习精讲
查看>>
数据结构与算法7-栈
查看>>
线性数据结构学习笔记
查看>>
Java并发编程 | 一不小心就死锁了,怎么办?
查看>>
(python版)《剑指Offer》JZ01:二维数组中的查找
查看>>
(python版)《剑指Offer》JZ06:旋转数组的最小数字
查看>>
(python版)《剑指Offer》JZ13:调整数组顺序使奇数位于偶数前面
查看>>
(python版)《剑指Offer》JZ28:数组中出现次数超过一半的数字
查看>>
(python版)《剑指Offer》JZ30:连续子数组的最大和
查看>>
(python版)《剑指Offer》JZ32:把数组排成最小的数
查看>>
(python版)《剑指Offer》JZ02:替换空格
查看>>
JSP/Servlet——MVC设计模式
查看>>
使用JSTL
查看>>
Java 8新特性:Stream API
查看>>