@lanxinyuchs 2015-01-06T03:37:46.000000Z 字数 3292 阅读 1351

RTOS

if (mutex->owner == thread)      {          /* it's the same thread */          mutex->hold ++;      } 

Mutual-exclusion semaphores can be taken recursively. This means that the semaphore can be taken more than once by the task that holds it before finally being released. Recursion is useful for a set of routines that must call each other but that also require mutually exclusive access to a resource.

/* Function A requires access to a resource which it acquires by taking   * mySem;    * Function A may also need to call function B, which also requires mySem:   */   /* includes */   #include "vxWorks.h"   #include "semLib.h"   SEM_ID mySem;   /* Create a mutual-exclusion semaphore. */   init ()       {       mySem = semMCreate (SEM_Q_PRIORITY);       }   funcA ()       {       semTake (mySem, WAIT_FOREVER);       printf ("funcA: Got mutual-exclusion semaphore\n");       ...        funcB ();       ...        semGive (mySem);       printf ("funcA: Released mutual-exclusion semaphore\n");       }   funcB ()       {       semTake (mySem, WAIT_FOREVER);       printf ("funcB: Got mutual-exclusion semaphore\n");       ...        semGive (mySem);       printf ("funcB: Releases mutual-exclusion semaphore\n");       }  

owner机制还有一个作用，就是通过优先级继承实现优先级翻转，参考stackoverflow上的一个解答:

Because the recursive mutex has a sense of ownership, the thread that grabs the mutex must be the same thread that release the mutex. In the case of non-recursive mutexes, there is no sense of ownership and any thread can usually release the mutex no matter which thread originally took the mutex. In many cases, this type of "mutex" is really more of a semaphore action, where you are not necessarily using the mutex as an exclusion device but use it as synchronization or signaling device between two or more threads.

Another property that comes with a sense of ownership in a mutex is the ability to support priority inheritance. Because the kernel can track the thread owning the mutex and also the identity of all the blocker(s), in a priority threaded system it becomes possible to escalate the priority of the thread that currently owns the mutex to the priority of the highest priority thread that is currently blocking on the mutex. This inheritance prevents the problem of priority inversion that can occur in such cases. (Note that not all systems support priority inheritance on such mutexes, but it is another feature that becomes possible via the notion of ownership).

If you refer to classic VxWorks RTOS kernel, they define three mechanisms:

mutex - supports recursion, and optionally priority inheritance
binary semaphore - no recursion, no inheritance, simple exclusion, taker and giver does not have to be same thread, broadcast release available
counting semaphore - no recursion or inheritance, acts as a coherent resource counter from any desired initial count, threads only block where net count against the resource is zero.

Linux, thankfully, does not provide recursive locks. This is widely considered a good thing. Although recursive locks might alleviate the self-deadlock problem, they very readily lead to sloppy locking semantics

• 私有
• 公开
• 删除