The general case is whether the synchronization object is re-enabled. In other words, you can get the same thread again if it already owns the lock. Another way to tell if an object is "affinity for a stream".
In .NET, the Monitor class (which implements the lock statement), Mutex, and ReaderWriterLock are repetitive. There are no semaphore and SemaphoreSlim classes, you can get your code into a dead end with a binary semaphore. The cheapest way to implement locking is with Interlocked.CompareExchange (), it will also not be re-enabled.
There is an additional cost associated with creating a re-entry of the synchronization object; it needs to keep track of which thread belongs to it, and how often the lock was received in the ownership flow. This requires storing Thread.ManagedId and a counter, two ints. This influenced the choice in C ++, for example, the C ++ 11 language specification, finally adding streams to the standard library. The std :: mutex class is not a repeat participant in this language, and offers to add a recursive version were rejected. They considered the overhead of making him a repeat participant too high. It’s a little difficult, perhaps a cost that is quite small compared to the amount of time spent debugging a random deadlock :) But this is a language in which there is not the slightest chance that obtaining a stream identifier can be guaranteed cheap as it is. NET
This is displayed in the ReaderWriterLockSlim class, which you can select. Note the RecursionPolicy property, which allows you to choose between NoRecursion and SupportsRecursion. NoRecursion mode is cheaper and makes it really thin.
source share