Примитивы синхронизации

Редактировал(а) Alexandr Fokin 2023/10/09 10:03

Типы примитивов

Конструкции пользовательского режима 
Конструкции режима ядра 
Гибридные конструкции синхронизации потоков 

Некоторые примитивы синхронизации

Конструкции пользовательского режима 
  1. Модификатор переменных, ограничивающий оптимизации компилятора c#.
  2. Класс, содержащий методы, которые помимо операции чтения/записи накладывают ограничение (барьер), не позволяющее процессору менять порядок выполнения команд.
Interlocked
https://learn.microsoft.com/ru-ru/dotnet/api/system.threading.interlocked?view=net-5.0
Предоставляет набор некоторых операций, гарантирующих атомарность выполнения.
Являет предпочтительным по сравнению с явной блокировкой.
  
Monitor (Гибридные конструкции
синхронизации потоков)

Реализуют идею критической секции. Ограничивает степень параллелизма на секциях, находящихся после Monitor.Enter, одним потоком.

LockОператор lock является оберткой над классом Monitor, его операциями Enter/Exit, обернутыми в try-finally.
Semaphore (Конструкции режима ядра)
SemaphoreSlim
Семафоры позволяют ограничить доступ выполнения кода определенным количеством потоков.
Mutex (Конструкции режима ядра)Используется для синхронизации на уровне операционной системы.
Может использоваться несколькими приложениями в рамках одной ОС.
ReaderWriterLock
ReaderWriterLockSlim (Гибридные конструкции
синхронизации потоков)
Позволяет ограничить параллелизм либо 1 писателем, либо многими читателями.
AutoResetEvent (Конструкции режима ядра)
ManualResetEven (Конструкции режима ядра)
Имеет 2 состояния (взведен и не взведен).
Позволяет ожидать взведенного состояния.
Содержит методы для взведения.
CountdownEvent (Гибридные конструкции
синхронизации потоков)
При инициализации задается значение счетчика.
Позволяет ожидать, когда значение счетчика будет равно 0.
Метод уменьшающий счетчик.
Spin* 

Материалы


Шаблон

При использовании инструментов важно освобождать освобождать блокировку, даже если в процессе выполнения логики возникнет исключение.
Во многих случаях имеет смысл реализовывать объект обертку, реализующую блокировку, и не допускающую неправильное использование.
Общий шаблон использования:

EnterLock();
try
{  
 //... Action
}
// catch {}
finally
{
  ReleaseLock();
}
Теги: