互斥锁陷阱:优先级反转死锁

Posted __2017__

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了互斥锁陷阱:优先级反转死锁相关的知识,希望对你有一定的参考价值。


摘自:

Mastering the FreeRTOS 7.3 Mutexes (and Binary Semaphores)


Priority Inversion


This Figure demonstrates one of the potential pitfalls of using a mutex to provide mutual
exclusion. The sequence of execution depicted shows the higher priority Task 2 having to wait
for the lower priority Task 1 to give up control of the mutex. A higher priority task being
delayed by a lower priority task in this manner is called ‘priority inversion’. This undesirable
behavior would be exaggerated further if a medium priority task started to execute while the
high priority task was waiting for the semaphore—the result would be a high priority task
waiting for a low priority task—without the low priority task even being able to execute. This
worst case scenario is shown in Figure below:

Figure.  A worst case priority inversion scenario


Priority inversion can be a significant problem, but in small embedded systems it can often be
avoided at system design time, by considering how resources are accessed
.


Priority Inheritance
OS mutexes and binary semaphores are very similar—the difference being that
mutexes include a basic ‘priority inheritance’ mechanism, whereas binary semaphores do not.
Priority inheritance is a scheme that minimizes the negative effects of priority inversion. It
does not ‘fix’ priority inversion, but merely lessens its impact by ensuring that the inversion is
always time bounded. However, priority inheritance complicates system timing analysis, and it
is not good practice to rely on it for correct system operation.
Priority inheritance works by temporarily raising the priority of the mutex holder to the priority of
the highest priority task that is attempting to obtain the same mutex. The low priority task that
holds the mutex ‘inherits’ the priority of the task waiting for the mutex. This is demonstrated by
Figure below. The priority of the mutex holder is reset automatically to its original value when it
gives the mutex back.

Figure. Priority inheritance minimizing the effect of priority inversion


As just seen, priority inheritance functionality effects the priority of tasks that are using the
mutex. For that reason, mutexes must not be used from an interrupt service routines.


Deadlock (or Deadly Embrace)

‘Deadlock’ is another potential pitfall of using mutexes for mutual exclusion. Deadlock is
sometimes also known by the more dramatic name ‘deadly embrace’.
Deadlock occurs when two tasks cannot proceed because they are both waiting for a resource
that is held by the other. Consider the following scenario where Task A and Task B both need
to acquire mutex X and mutex Y in order to perform an action:
    1. Task A executes and successfully takes mutex X.
    2. Task A is pre-empted by Task B.
    3. Task B successfully takes mutex Y before attempting to also take mutex X—but mutex
       X is held by Task A so is not available to Task B. Task B opts to enter the Blocked
       state to wait for mutex X to be released.
    4. Task A continues executing. It attempts to take mutex Y—but mutex Y is held by Task
       B, so is not available to Task A. Task A opts to enter the Blocked state to wait for
       mutex Y to be released.


At the end of this scenario, Task A is waiting for a mutex held by Task B, and Task B is waiting
for a mutex held by Task A. Deadlock has occurred because neither task can proceed.
最简单的死锁场景:自死锁。一个任务试图去获得一个自己已经持有的锁。
As with priority inversion, the best method of avoiding deadlock is to consider its potential at
design time, and design the system to ensure that deadlock cannot occur. In particular, and
as previously stated in this book, it is normally bad practice for a task to wait indefinitely
(without a time out) to obtain a mutex. Instead, use a time out that is a little longer than the
maximum time it is expected to have to wait for the mutex—then failure to obtain the mutex
within that time will be a symptom of a design error, which might be a deadlock.
In practice, deadlock is not a big problem in small embedded systems, because the system
designers can have a good understanding of the entire application, and so can identify and
remove the areas where it could occur.

以上是关于互斥锁陷阱:优先级反转死锁的主要内容,如果未能解决你的问题,请参考以下文章

在优先级反转问题上,我们应该更改互斥锁或线程的属性吗?

Linux同步机制 - 基本概念(死锁,活锁,饿死,优先级反转,护航现象)

Linux-互斥-互斥锁-死锁

ucos实时操作系统学习笔记——任务间通信(互斥锁)

golang-锁-死锁,互斥锁,读写锁

五互斥量概念用法死锁