Как взаимные исключения реализованы?

Поскольку Вы определили g (), чтобы быть виртуальными, наиболее полученный g () будет искаться в vtable из класса и звонил независимо от типа, Ваш код в настоящее время получает доступ к нему.

Посмотрите FAQ C++ на виртуальных функциях .

54
задан static_rtti 27 September 2009 в 21:01
поделиться

5 ответов

Ознакомьтесь с описанием машинной инструкции Test-and-set в Википедии, в которой упоминается, как атомарные операции выполняются на машинном уровне. Я могу представить, что большинство реализаций мьютексов на уровне языка полагаются на поддержку машинного уровня, такую ​​как Test-and-set.

31
ответ дан 7 November 2019 в 08:07
поделиться

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

  • При использовании счетчика он может стать семафором.
  • Мьютекс является отправной точкой для критической секции, которая использует мьютекс внутри, чтобы увидеть, может ли он войти в секцию кода. Если мьютекс свободен, он устанавливает мьютекс и выполняет код, только чтобы освободить мьютекс по завершении. Когда критическая секция замечает, что мьютекс заблокирован, он может дождаться освобождения мьютекса.

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

Теперь, имея эти базовые знания о внутреннем устройстве мьютексов, все, что я надеюсь, - это то, что вы собираетесь использовать одну реализацию, которая полагается на ядро ​​и находящееся ниже оборудование. Это были бы самые надежные. (Если оборудование поддерживает их.) Если мьютекс, который вы используете, не работает на этом уровне ядра / оборудования, он все еще может быть надежным, но я бы посоветовал не использовать его, если нет альтернативы.

Как насколько мне известно, Windows, Linux и. Все NET будут использовать мьютексы на уровне ядра / оборудования.

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

10
ответ дан 7 November 2019 в 08:07
поделиться

Interlocked.CompareExchange достаточно для реализации спин-блокировок. Однако это довольно сложно сделать правильно. См. блог Джо Даффи для примера задействованных тонкостей.

2
ответ дан 7 November 2019 в 08:07
поделиться

Я использовал Reflector.NET для декомпиляции исходного кода для System.Threading.ReaderWriterLockSlim , который был добавлен в последнюю версию .NET framework.

В основном это было использует Interlocked.CompareExchange , Thread.SpinWait и Thread.Sleep для достижения синхронизации. Есть несколько экземпляров EventWaitHandle (объект ядра), которые используются при некоторых обстоятельствах.

Также добавлена ​​некоторая сложность для поддержки повторного входа в одном потоке.

Если вас интересует эта область и работая в .NET (или, по крайней мере, можете прочитать его), вам может быть интересно проверить этот класс.

-1
ответ дан 7 November 2019 в 08:07
поделиться

Основываясь на предложении Адамски test-and-set , вам также следует взглянуть на концепция «быстрых мьютексов в пользовательском пространстве» или фьютексов .

Фьютексы обладают желаемым свойством, заключающимся в том, что они не требуют системного вызова ядра в общих случаях блокировки или разблокировки неконтролируемого мьютекс. В этих случаях код пользовательского режима успешно использует атомарную операцию сравнения и обмена (CAS) для блокировки или разблокировки мьютекса.

Если CAS терпит неудачу, мьютекс будет оспорен, а системный вызов ядра - - sys_futex под Linux - необходимо использовать либо для ожидания мьютекса (в случае блокировки), либо для пробуждения других потоков (в случае разблокировки).

Если вы серьезно относитесь к реализации этого сами,

23
ответ дан 7 November 2019 в 08:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: