Вопрос

Представьте, что вы используете параллелизм в многоядерной системе.

Разве не возможно, что те же инструкции могут быть выполнены одновременно?

Возьмите следующий код:

int i = 0;

if( blockingCondition )
{
  lock( objLock )
  {
    i++;
  }
}

В моей голове кажется, что в системе с несколькими ядрами и параллелизмом вполне возможно, что в тот же момент можно проверить блокировку в тот же момент, что приводит к попытке блокировки, и так далее ... это истинный?

Если это так, как вы можете обеспечить синхронизацию в процессорах?

Кроме того, обрабатывает ли .NET TPL этот тип синхронизации? А как насчет других языков?

РЕДАКТИРОВАТЬОбратите внимание, что это нет о нитках, но задачах и параллельно-процессе.

Редактировать 2Хорошо, спасибо за информацию всех. Итак, правда ли, что ОС гарантирует, что запись в память сериализуется, обеспечивая многоядерную синхронизацию через WALTILE READS?

Это было полезно?

Решение

Замок, как вы описали здесь, это «Монитор«Стиль блокировки на OBJLOCK. Как вы уже отмечали, все возможное, в рамках многоядерной системы, для двух« заблокированных »вызовов начинать одновременно. Тем не менее, любая среда применения высокого уровня, которая использует мониторы, будет переведена на монитор в семафор Запросы (или, в зависимости от вашей ОС и языковых подробностей, запросов MUTEX) в скомпилированном байтовом коде.

Семафоры реализуются на операционной системе и / или уровнях оборудования, а языки более высокого уровня связывают с ними. На уровне ОС они «гарантированы», чтобы быть атомным. То есть любая программа, приобретая семафор, гарантированно будет единственным, что делает так в этот момент. Если две программы или два потока в рамках программы пытаются приобрести блокировку одновременно, один пойдет первым (и преуспеть), а другой пойдет второй (и сбой).

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

В результате этого, как кодера приложения, вы можете с уверенностью предположить, что «Lock (objlock)» будет атомным вызовом, независимо от того, сколько процессоров вы подключаете к своей системе.

Другие советы

Чтобы понять, почему это работает, имейте в виду:

  1. Блокировка блокировки (т.е. увеличение замка семафор на объекте) - это операция, которая блокирует, если объект уже заблокирован.

  2. Два шага lock, а) проверка семафора блокировки бесплатна, б) и фактически запирает объект, выполняется'одновременно' - то есть они монолит или атомный Операция в отношении взаимосвязи между процессором и памятью.

Следовательно, вы можете увидеть это, если 2 потока введите свой if-block, одна из двух потоков приобретет замок, а другая будет блокировать, пока первый не закончил if.

Ваша забота именно поэтому нам нужен специальный механизм, как lock и не может просто использовать логический флаг.

Решение вашей «одновременной» проблемы в алгоритме, который lock (который звонит Monitor.Enter()) использует. Он включает в себя барьеры памяти и знание очень низкоуровневой механики памяти, чтобы гарантировать, что нить № 2 может приобрести блокировку одновременно.

Примечание: я говорю о .NET только, а не Java.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top