Память Барьер по заявлению блокировки

Я обычно использую шаблон дизайна Singleton для чего-то подобного http://en.wikipedia.org/wiki/Singleton_pattern . Я сделаю основную форму, которую приложение запускает под синглоном, а затем создайте аксессоры для форм и элементов управления, которые я хочу коснуться в других областях. Другие формы могут либо получить указатель на элемент управления, который они хотят изменить, либо данные в основной части приложения, которые они хотят изменить.

Другой подход - настроить события на разных формах для обмениваться сообщениями и использовать основную форму как своего рода хаб для передачи сообщений событий из одной формы в другую в приложении.

13
задан trooper 15 May 2015 в 21:01
поделиться

2 ответа

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

  • Ограничение захвата: барьер памяти, при котором другие операции чтения и записи не могут перемещаться перед ограничением.
  • Освободить ограждение: барьер памяти, в котором другие операции чтения и записи не могут перемещаться после ограждения.

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

Ключевое слово volatile создает полузаборы. Чтения изменчивых полей имеют семантику получения, а записи - семантику выпуска. Это означает, что никакая инструкция не может быть перемещена до чтения или после записи.

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

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

Итак, чтобы ответить на ваши вопросы:

  1. С точки зрения одного потока ... да. С точки зрения другого потока ... нет.

  2. Это зависит от обстоятельств. Это может сработать, но мне нужно лучше понимать, чего вы пытаетесь достичь.

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

30
ответ дан 1 December 2019 в 07:51
поделиться

Ключевое слово volatile здесь ничего не делает. У него очень слабые гарантии, не подразумевает барьер памяти. Ваш код не показывает, что создается другой поток, поэтому трудно угадать, требуется ли блокировка. Однако это жесткое требование, если два потока могут выполнять Update () одновременно и использовать один и тот же объект.

Помните, что указанный вами код блокировки ничего не блокирует. У каждого потока будет свой собственный экземпляр объекта «шкафчик». Вы должны сделать его частным полем вашего класса, созданным конструктором или инициализатором. Таким образом:

private object locker = new object();

private void Update()
{
    lock (locker)
    {
        _usingMethod1 = true;
        SomeProperty = FooMethod();
        //..
        _usingMethod1 = false;
    }
}

Обратите внимание, что также будет гонка по назначению SomeProperty.

4
ответ дан 1 December 2019 в 07:51
поделиться
Другие вопросы по тегам:

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