C # Блокированные функции как механизм блокировки?

Пока я читал о механизме блокировки ReaderWriterLockSlim , был этот парень, который предположил, что функции Interlock могут использоваться для более тонкой блокировки

Кроме того, я нашел здесь еще один ответ от Марка:

… Writes вносят изменения в клонированную копию, а затем используют Interlocked.CompareExchange для замены ссылки (повторное применение их изменения, если другой stream мутировал ссылку в промежутке времени).

Ну, В настоящее время все, что я знаю об объекте Interlocked , заключается в том, что он используется (в многопоточной среде) для выполнения атомных additions , compare , compareExchange операций compareExchange . (и я знаю, как его использовать)

Но ( и вот мой вопрос ) –

Вопрос

Как я могу использовать его в качестве блокировки ? (пример кода будет высоко оценен)

редактировать

Для простоты я вставляю этот код ( который не является streamобезопасным – если Go был вызван двумя streamами одновременно, можно было бы получить ошибку деления на нуль ):

 class ThreadUnsafe { static int _val1 = 1, _val2 = 1; static void Go() { if (_val2 != 0) Console.WriteLine (_val1 / _val2); _val2 = 0; } } 

Как я могу использовать блокировку для замены блокировки (которая бы решила проблему)?

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

Тем не менее, существует много и много вещей, которые вы не можете сделать с помощью Interlocked которую вы можете делать под обычной блокировкой. Например, все, что связано с модификацией более чем одной переменной, как правило, не может быть выполнено с помощью Interlocked , поэтому вы не сможете использовать ее для своего примера.

Interlocked может помочь разработчикам реализовать механизм блокировки, хотя вы можете также использовать встроенные. Для большинства шлюзов требуется поддержка ядра для прерывания заблокированного streamа до тех пор, пока блокировка не станет доступной. Таким образом, единственный вид блокировки, который вы можете реализовать с помощью Interlocked одиночку, – это прямая блокировка: блокировка, которую streamи постоянно пытаются получить, пока она не будет работать.

 class InterlockedLock { private int locked; public void Lock() { while (Interlocked.CompareExchange(ref locked, 1, 0) != 0) continue; // spin } public void Unlock() { locked = 0; } } 

В этом примере locked изначально равна нулю. Когда stream пытается получить его в первый раз, locked становится 1, и последующие streamи, пытающиеся locked ее, будут вращаться, пока кто-то не вызовет Unlock чтобы снова locked 0.

Блокировка с Interlocked выполняется путем замены нового значения на старое значение только в том случае, если старое значение не изменилось. Если мы попробуем еще раз, пока это не произойдет (rotation).

Это можно использовать для замены мелкозернистых замков, которые обновляют только одно значение или реализуют легкий механизм блокировки, такой как SpinLock .

Пример :

 private int _value; int oldValue; int originalValue; do { oldValue = _value; originalValue = Interlocked.CompareExchange(ref _value, newValue, oldValue); } while (originalValue != oldValue); 

Вместо :

 lock(_lock) { _value = newValue; }