Общий случай: является ли объект синхронизации повторным абитуриентом. Другими словами, можно снова получить тот же поток, если он уже владеет блокировкой. Другой способ сказать, является ли объект «сродством к потоку».
В .NET класс Monitor (который реализует оператор блокировки), Mutex и ReaderWriterLock являются повторными. Классы Семафор и СемафорСлим - , а не, вы можете получить код в тупик с помощью двоичного семафора. Самый дешевый способ реализации блокировки - с Interlocked.CompareExchange(), он также не будет повторно включен.
Существует дополнительная стоимость, связанная с созданием повторного входа объекта синхронизации, ему необходимо отслеживать, какой поток принадлежит ему, и как часто блокировка была получена на принадлежащем потоке. Для этого требуется хранить Thread.ManagedId и счетчик, два ints. Это повлияло на выбор в C++, например, спецификацию языка C++ 11, наконец, добавив потоки в стандартную библиотеку. Класс std :: mutex: не повторный участник на этом языке, и предложения по добавлению рекурсивной версии были отклонены. Они считали накладные расходы на то, чтобы сделать его повторным участником слишком высоким. Немного тяжело, возможно, стоимость, которая довольно незначительна против количества времени, затрачиваемого на отладку случайного тупика :) Но это язык, на котором нет ни малейшего шанса, что получение идентификатора потока может быть гарантировано дешевым, как оно есть. СЕТЬ.
Это показано в классе ReaderWriterLockSlim, который вы можете выбрать. Обратите внимание на свойство RecursionPolicy, позволяющее выбирать между NoRecursion и SupportsRecursion.Режим NoRecursion дешевле и делает его действительно slim.
Семафоры работают так, как я и предполагал, вот мой код http://stackoverflow.com/a/17194374/98491 Это просто 'private static ss = new SemaphoreSlim (1, 1);' и в коде я завернул 'ss. Wait(); 'и' ss.Release() 'в блок try/finally. –
Отличный ответ! +1 для объяснения того, как работают все замки, а не только того, кто спрашивает о – Thresh