Mutex stands for mutual exclusion – they are explicitly designed to be used in situations where access to a shared resource should be mutually exclusive – meaning the shared resource can only be used by one piece of code at a time. At their heart, mutexes are simply binary semaphores with one (very important) difference: priority inheritance. In the previous example, we saw the highest-priority task waiting on two lower-priority tasks to complete, which caused a priority inversion. Mutexes address this issue with something called priority inheritance.
When a higher-priority task attempts to take a mutex and is blocked, the scheduler will elevate the priority of the task that holds the mutex to the same level as the blocked task. This guarantees that the high-priority task will acquire the mutex and run as soon as possible.