Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
 Аватар для nnnikotinnn995
7 / 7 / 4
Регистрация: 07.07.2011
Сообщений: 583

lock в условие или в цикле

09.12.2019, 08:48. Показов 5505. Ответов 72

Студворк — интернет-сервис помощи студентам
Здравствуйте. Как известно одна переменная в разных потоках требует блокировки, иначе результат изменения переменной будет не предсказуемый. Но если в одном потоке переменная (например) bool меняется, а во втором только проверяется, то обязательно ли блокировать изменение переменной или это лишнее? Если bool меняется асинхронно в обоих потоках, то да-надо. Но если меняется только в одном, а во втором просто проверяется или в if() или в while, то зачем что то блокировать?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
bool ExitFromGame=false;
private Thread myThreadnN1, myThreadnN2;
static void Main(string[] args){
myThreadnN1 = new Thread(Exit);myThreadnN1.Start();
myThreadnN2= new Thread(Listen); myThreadnN2.Start();
}
private void Listen() {
                while(!ExitFromGame) {//как это блокировать и надо ли?
                }
}
public void Exit() {
         Thread.Sleep(1000);ExitFromGame=true;//надо ли писать lock(this){ExitFromGame=true;} ?
        }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.12.2019, 08:48
Ответы с готовыми решениями:

Acer aspire 5552G-N974G64Mikk Проблема с Caps Lock, Num Lock, Scroll Lock
Вообщем у меня такая же проблемма https://www.cyberforum.ru/notebooks/thread552722.html Небольшая проблема на ноутбуке, когда...

Вывести на экран в символическом виде состояние NUM LOCK, CAPS LOCK и SCROLL LOCK
Помогите решить задачку на турбо си Выводить на экран в символическом виде состояние NUM LOCK, CAPS LOCK и SCROLL LOCK (вкл. / выкл.),...

Клавиатура мигает всеми тремя индикаторами Caps Lock, Scroll Lock и Num Lock и соответственно не работает!
Здравствуйте парни и девушки! Столкнулся с такой проблемой! Имеется клавиатура Genius Ergomedia 700! Так вот. Начал замечать интересную...

72
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 15:10
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
может ли компилятор как-то оптимизировать, кешировать этот адрес, если он используется часто.
Что такое кешировать?
Как минимум для этого должна быть ссылка на кеш.
Как может быть одна ссылка быть оптимальнее другой?

А с учётом динамического выделения памяти, сбора мусора и т.п. с кешем только проблем добавится для дополнительной синхронизации.

Фактически, там где-то в глубинах .Net, какое-то кеширование происходит, так как физическая адресация объекты в памяти не постоянна (можно зафиксировать, но это не относится к теме вопроса).
Но уровне Шарпа от нас всё это инкапсулировано и на этом уровне никакого кеширования ссылок нет.

Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Если атомарность не влияет на то, нужно ли лочить или нет, то какая польза от знания, атомарна ли операция?
kolorotur, приводит экстремальные сценарии в которых атомарность не гарантирует потокобезобозасности.
В реальных приложения 99.99% разработчиков никогда за свою карьеру с таким не столкнутся.

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

Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Почему? Какой-то поток начал изменять адрес Name, наполовину изменил и тут другой поток считывает этот адрес для доступа к Name?
Как это "наполовину изменил"?
Изменение Name - это запись одного машинного слова.
Производится за полтакта процессора.

Добавлено через 3 минуты
Цитата Сообщение от kolorotur Посмотреть сообщение
Если логика приложения полагается на то, что значение свойства всегда должно быть считано свежее, то осмысленно.
Но это внешние операции.
И использовать для синхронизации внешних операций экземпляр NameClass или любой другой локер - не имеет никакой разницы.
Конечно, можно придумать массу сценариев в которой изменение какой-то переменой вызывает какую-то логику и на время её работы другие потоки не должны работать со старым значением.
Но к изменению самого свойства в NameClass это не имеет отношения.
1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
09.01.2022, 15:13
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но это внешние операции.
Класс либо потокобезопасен, либо нет.
Если класс документируется как потокобезопасный, то вся синхронизация производится как часть его реализации, если нет, то внутри синхронизировать ничего не нужно и это должен делать внешний код, использующий класс в многопоточном сценарии — см. List<T> и пр.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 15:20
Цитата Сообщение от kolorotur Посмотреть сообщение
Если класс документируется как потокобезопасный,
ОК!

Выше я дал две реализации NameClass.
В каком сценарии может первая работать неправильно, а вторая (с локерами в свойстве) правильно?

Допустим если есть событие об изменении, то имеет смысл локировать геттер

C#
1
2
3
4
5
6
7
8
9
10
public class NameClass
{
     public event Action NameChanged;
     private string name;
     public string Name
    {
         get => name;
         set {lock(this) {name = value; NameChanged?.Invoke();}
    }
}
Но это дополнительная логика, которой не было в вопросе.
0
109 / 52 / 16
Регистрация: 09.06.2021
Сообщений: 480
09.01.2022, 15:24
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Что такое кешировать?
Это вопрос писателям компиляторов. Предполагаю, что если адрес поместить в какой-нибудь регистр, то доступ будет быстрее. Т.е. то же, что с кешированием bool.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но уровне Шарпа от нас всё это инкапсулировано и на этом уровне никакого кеширования ссылок нет.
А на уровне Шарпа не сказано, что если доступ к переменной (ее адресу) из разных потоков, то надо лочить?
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Как это "наполовину изменил"?
Изменение Name - это запись одного машинного слова.
Так же как может один поток начать изменять decimal, а другой в это время считывать.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 15:35
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Предполагаю, что если адрес поместить в какой-нибудь регистр, то доступ будет быстрее. Т.е. то же, что с кешированием bool.
Для уровня Шарпа думать об этом не следует.
Этим занимается, наверное, даже не компилятор Шарпа, а виртуальная машина CLR уже при запуске CIL.

Цитата Сообщение от Fylhtq05 Посмотреть сообщение
А на уровне Шарпа не сказано, что если доступ к переменной (ее адресу) из разных потоков, то надо лочить?
Если этот доступ не атомарный.
Допустим, в объекте несколько зависимых свойств.
Вам надо их прочитать и произвести какие-то действия.
Сам объект хранится в локальной переменной, но для чтения его свойств вам приходится обращаться уже к вложенным переменным несколькими командами.
И если в это время другой поток начнёт изменять свойства объекта, то вы может получить при чтении часть старых и часть новых значений свойств.
В таких сценариях следует реализовывать локированные транзакции для чтения и записи все свойств скопом.

Добавлено через 2 минуты
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Так же как может один поток начать изменять decimal, а другой в это время считывать.
decimal, вроде, ни на какой платформе не атомарный тип.

Добавлено через 1 минуту
А string - это ссылочный иммутабельный тип.
Создаётся новая строка и уже после этого свойству Name будет присвоена просто ссылка на эту строку.
Присвоение ссылки - это уже атомарная операция.
0
109 / 52 / 16
Регистрация: 09.06.2021
Сообщений: 480
09.01.2022, 15:40
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Для уровня Шарпа думать об этом не следует.
Почему? Если адрес Name может кешироваться, то лочить надо.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если этот доступ не атомарный.
Почему изменение адреса Name атомарно, а изменение decimal нет?

Добавлено через 2 минуты
Цитата Сообщение от nnnikotinnn995 Посмотреть сообщение
Но если в одном потоке переменная (например) bool меняется, а во втором только проверяется, то обязательно ли блокировать изменение переменной или это лишнее?
Имхо, надо. Т.к. bool может кешироваться, если нет lock.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 15:46
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Почему? Если адрес Name может кешироваться, то лочить надо.
Потому что работа с таким кешированием на уровне регистров это ниже уровня Шарпа.
И lock в этом не помощник.
За безопасность на таком уровне отвечает CLR.

Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Почему изменение адреса Name атомарно, а изменение decimal нет?
Потому, что для записи ссылки требуется изменить одно машинное слово.
А для decimal два или четыре (зависит от архитектуры процессора).

Добавлено через 43 секунды
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Имхо, надо. Т.к. bool может кешироваться, если нет lock.
Не может и не надо.

Добавлено через 2 минуты
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А для decimal два или четыре (зависит от архитектуры процессора).
Например, для long нужно изменить 64 бита.
В зависимости от архитектуры процессора это может быть оно машинное слово, а может быть и два.
Поэтому, в общем случае, изменение операции с long не атомарны.
Но в архитектуре x-64 - атомарны.
0
109 / 52 / 16
Регистрация: 09.06.2021
Сообщений: 480
09.01.2022, 15:48
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Потому что работа с таким кешированием на уровне регистров это ниже уровня Шарпа.
В чем отличие от кеширования bool, которое надо учитывать и, соответственно, оборачивать в класс и, соответственно оборачивать в класс и лочить?
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Потому, что для записи ссылки требуется изменить одно машинное слово.
Ну да, меняется целое машинное слово, а не просто какой-нибудь разряд, и это атомарная операция? Тогда надо считать, что изменение char атомарно?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 16:02
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Тогда надо считать, что изменение char атомарно?
Я же дал вам ссылку.
Прочитайте. Или так и будете за каждый тип отдельно интересоваться?

Цитата Сообщение от Fylhtq05 Посмотреть сообщение
В чем отличие от кеширования bool, которое надо учитывать и, соответственно, оборачивать в класс и, соответственно оборачивать в класс и лочить?
Кеширование в регистрах учитывать на Шарпе никогда не надо.
На уровня Шарпа такого кеширования просто нет.

Локирование bool (в упаковке) или другого атомарного типа нужно в том случае, когда его изменение взывает какую-то зависимую логику, на время работы которой это значение должно быть неизменным.

Простейший пример:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class SumClass
{
     private int a;
     private int b;
     private int sum;
 
     public void SetA(int a)
     {
          lock(this)
          {
              this.a = a;
              sum = this.a + this.b;
          }
     }
     public void SetB(int b)
     {
          lock(this)
          {
              this.b = b;
              sum = this.a + this.b;
          }
     }
 
     public (int a, int b, int sum) Get()
     {
          lock(this)
          {
              return (a, b, sum);
          }
     }
}
0
109 / 52 / 16
Регистрация: 09.06.2021
Сообщений: 480
09.01.2022, 16:18
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Кеширование в регистрах учитывать на Шарпе никогда не надо.
В теме В чем смысл проверки IsCancellationRequested в циклах? меня убедили, что учитывать кеширование надо:
Цитата Сообщение от kolorotur Посмотреть сообщение
Суть та же: пока b == false, цикл будет крутиться (не важно что там происходит).
Постройте программу в режиме Release и запустите не из студии, чтобы отладчик не мешался — после ввода Y цикл не завершится, потому что значение будет кешировано.
Цитата Сообщение от kolorotur Посмотреть сообщение
Атомарность — это о другом.
Лочить доступ из разных потоков нужно даже для атомарных операций, или использовать барьеры.
Цитата Сообщение от kolorotur Посмотреть сообщение
Я вот тоже не знаю в каких случаях рантайм и компилятор производят всякие оптимизации, которые могут повлиять на ход работы программы.
Но вот что известно достоверно, т.к. это задокументировано в спеках языка и рантайма — это то, что при обращении к одному участку памяти из разных потоков в отсутствие синхронизации, эти потоки могут наблюдать абсолютно разные значения.
Так же там задокументировано то, что компилятор может переставлять инструкции по чтению и записи памяти как ему угодно при условии, что наблюдаемый в однопоточном приложении эффект будет неизменным. В разных потоках необходимо устанавливать т.н. барьеры, предотвращающие эти перестановки.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 16:37
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
В теме В чем смысл проверки IsCancellationRequested в циклах? меня убедили, что учитывать кеширование надо:
Там речь совсем о другом.
И к работе с регистрами это не имеет ни какого отношения.

Там есть логика зависимая от флагов и речь идёт об учитывании этой логики.
Кроме этого при создании .Net типов стараются учесть самые невероятные и редкие сценарии.

Допустим, как писал kolorotur, вы можете писать приложение для 8-битового контролера, отменить вырывание в памяти и т.д.
В этих случаях даже int и short уже нельзя будет считать атомарными.
Но часто вы пишите на Шарпе многопоточные приложения для 8-битовых контролеров?

Добавлено через 11 минут
Fylhtq05, гарантированная атомарность на всех платформах обеспечивает только класс Interlocked Class.
0
109 / 52 / 16
Регистрация: 09.06.2021
Сообщений: 480
09.01.2022, 16:41
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Там речь совсем о другом.
И к работе с регистрами это не имеет ни какого отношения.
И там и здесь - о кешировании. А в регистрах это кешировании или нет не знаю, я писал:
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Это вопрос писателям компиляторов. Предполагаю, что если адрес поместить в какой-нибудь регистр, то доступ будет быстрее. Т.е. то же, что с кешированием bool.
Т.е. кешироваться так же, как bool (а может и иначе), а как это кеширование происходит на уровне железа не знаю.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Допустим, как писал kolorotur, вы можете писать приложение для 8-битового контролера, отменить вырывание в памяти и т.д.
В той ссылке kolorotur привел пример кеширования для обычных процессоров. Чем объяснил невозможность использования bool вместо IsCancellationRequested в циклах.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 16:56
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Т.е. кешироваться так же, как bool (а может и иначе), а как это кеширование происходит на уровне железа не знаю.
Для начала вам надо понять разницу между компилированием Шарпа и компилированием Плюсов.
Для Плюсов создаётся машинный код, а для Шарпа CIL.
И, теоретически, один и тот же CIL может исполняться на любой архитектуре, в том числе и там где, вообще, не предусмотрено никаких регистров.

Работая на Шарпе вы не работаете с реальной памятью, регистрами т .п.
Те же ссылки хранящиеся в переменных могут быть изменены при перераспределении физической памяти.
И ответственность за эту синхронизацию несёт уже CLR, а не Шарп.
У вас может быть ссылка на один объекте в десятках разных переменных.
И в какой-то момент CLR начнёт менять эти ссылки, но менять она их будет так, что для Шарпа все эти переменные всегда, в любой момент времени указывают на один и тот же объект.
Без разницы где он находится в памяти, в регистре, или в кеше на диске.

Добавлено через 6 минут
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
В той ссылке kolorotur привел пример кеширования для обычных процессоров. Чем объяснил невозможность использования bool вместо IsCancellationRequested в циклах.
Нет.
Но объяснил, что одного флага иногда для этого мало.
Нужна ещё некая инфраструктура для правильной работы с таким флагам.
И речь шла о том, следует ли её каждый раз реализовывать самому или использовать уже имеющийся тип с такой логикой.

В простых случаях (>90% приложений), простой флаг без проблем можно использовать вместо токена отмена.

Единственный случай где невозможно без него реализовать - это отмена созданной, но не запущенной задачи.
Заменить нельзя, поскольку это является частью реализации тасков.
0
109 / 52 / 16
Регистрация: 09.06.2021
Сообщений: 480
09.01.2022, 17:06
Добавлено через 4 минуты
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Нет.
Но объяснил, что одного флага иногда для этого мало.
Ну как же нет?
Цитата Сообщение от kolorotur Посмотреть сообщение
Постройте программу в режиме Release и запустите не из студии, чтобы отладчик не мешался — после ввода Y цикл не завершится, потому что значение будет кешировано.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 17:31
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Ну как же нет?
Это не кеширование, в том смысле, котором используете вы.
Это разная оптимизация кода.
И к потокобезопасности это не имеет никакого отношения.
В том числе никакое локирование не поможет это решить.
0
109 / 52 / 16
Регистрация: 09.06.2021
Сообщений: 480
09.01.2022, 17:36
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Это не кеширование, в том смысле, котором используете вы.
Это кеширование в том смысле, который использует kolorotur?
Он прав, что причиной является кеширование bool?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 18:16
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Он прав, что причиной является кеширование bool?
Что такое кеширование?
Это временное запоминание значение в какой-то быстро доступной памяти для ускорения работы с ней.

Я думаю, здесь проблема не в этом, а то в том, что по разному компилируется при разных оптимизациях.

Пример:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System.Threading.Tasks;
 
namespace Examp
{
    public class CancelFlag
    {
        public bool Flag;
 
        public Task<int> Start()
        {
            Flag = false;
            Task.Delay(100).ContinueWith(_ => Flag = true);
            return Task.Run(PrivateStart);
        }
        private int PrivateStart()
        {
            int sum = 0;
            while (!Flag)
                sum++;
 
            return sum;
        }
    }
}
CIL метода PrivateStart для Debug:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.method private hidebysig instance int32 
        PrivateStart() cil managed
{
  // Размер кода:       28 (0x1c)
  .maxstack  2
  .locals init (int32 V_0,
           bool V_1,
           int32 V_2)
  IL_0000:  nop
  IL_0001:  ldc.i4.0
  IL_0002:  stloc.0
  IL_0003:  br.s       IL_0009
  IL_0005:  ldloc.0
  IL_0006:  ldc.i4.1
  IL_0007:  add
  IL_0008:  stloc.0
  IL_0009:  ldarg.0
  IL_000a:  ldfld      bool Examp.CancelFlag::Flag
  IL_000f:  ldc.i4.0
  IL_0010:  ceq
  IL_0012:  stloc.1
  IL_0013:  ldloc.1
  IL_0014:  brtrue.s   IL_0005
  IL_0016:  ldloc.0
  IL_0017:  stloc.2
  IL_0018:  br.s       IL_001a
  IL_001a:  ldloc.2
  IL_001b:  ret
} // end of method CancelFlag::PrivateStart
Для Release:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.method private hidebysig instance int32 
        PrivateStart() cil managed
{
  // Размер кода:       18 (0x12)
  .maxstack  2
  .locals init (int32 V_0)
  IL_0000:  ldc.i4.0
  IL_0001:  stloc.0
  IL_0002:  br.s       IL_0008
  IL_0004:  ldloc.0
  IL_0005:  ldc.i4.1
  IL_0006:  add
  IL_0007:  stloc.0
  IL_0008:  ldarg.0
  IL_0009:  ldfld      bool Examp.CancelFlag::Flag
  IL_000e:  brfalse.s  IL_0004
  IL_0010:  ldloc.0
  IL_0011:  ret
} // end of method CancelFlag::PrivateStart
1
109 / 52 / 16
Регистрация: 09.06.2021
Сообщений: 480
09.01.2022, 20:03
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я думаю, здесь проблема не в этом, а то в том, что по разному компилируется при разных оптимизациях.
Я проверил код с lock, он работает в отличие от кода без lock:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class ForLock
        {
            public static bool b = false;
        }
        static object olock = new();
        static void Main(string[] args)
        {
            Task task1 = new Task(() => Factorial(5));
            task1.Start();
 
            Console.WriteLine("Введите Y для отмены операции или любой другой символ для ее продолжения:");
            string s = Console.ReadLine();
            if (s == "Y")
                lock (olock)
                {
                    ForLock.b = true;
                }
 
            Console.ReadLine();
        }
        static void Factorial(int x)
        {
            int result = 1;
            while (true)
            {
                bool b; lock (olock)
                {
                    b = ForLock.b;
                }
                if (b) break;
                result++;
            }
            Console.WriteLine("Операция прервана токеном");
        }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16154 / 11275 / 2890
Регистрация: 21.04.2018
Сообщений: 33,157
Записей в блоге: 2
09.01.2022, 20:22
Fylhtq05, в данном случае достаточно вставить
C#
7
        public volatile bool Flag;
Добавлено через 6 минут
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
Я проверил код с lock, он работает в отличие от кода без lock:
Дело не в самом lock, а то что компилятор по другому интерпретирует код в котором есть lock.
Фактически для внешних переменных используемых в lock он как бы добавляет volatile в их объявление.

Добавлено через 2 минуты
То есть проблема именно не в кешировании как таковом, а то что при разных оптимизациях создаётся разный CIL код.
Локальное считывание внешних переменных всегда есть в CIL.
А вот логика повторного внешнего считывания при некоторых оптимизациях компилятором опускается.

Добавлено через 4 минуты
Оптимизация порой создаёт такие проблемы.
Ведь компилятор не может залезть в голову разработчика и узнать как он ожидает работу кода.
Поэтому приходится либо отказываться от оптимизации, либо как-то изменять код чтобы компилятор "понял мысли" разработчика.

Добавлено через 2 минуты
kolorotur, volatile достаточно для решения подобной проблемы или есть сценарии где это не поможет?
1
109 / 52 / 16
Регистрация: 09.06.2021
Сообщений: 480
09.01.2022, 20:24
Цитата Сообщение от Элд Хасп Посмотреть сообщение
в данном случае достаточно
Я это писал В чем смысл проверки IsCancellationRequested в циклах?
Цитата Сообщение от Fylhtq05 Посмотреть сообщение
При объявлении bool надо в таком случае писать volatile.
На что был ответ:
Цитата Сообщение от kolorotur Посмотреть сообщение
volatile отключает оптимизации по перемещению инструкций чтения/записи относительно друг друга для этой переменной.
Т.е. отключает ровно один тип оптимизации из многих, производимых рантаймом и компилятором.
Т.е. по мнению kolorotur это не решает проблему.
И все же, то как ведет себя релиз это соответствует документации? Или вы считаете что лочить bool вообще-то не надо?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.01.2022, 20:24

Работа с клавиатурой (клавиши num lock, caps lock, scroll lock)
определить состояние статуса клавиш &quot; num lock, caps lock,scroll lock &quot; с отображением и их измением на экране

Оптимизирует ли компилятор выражения в цикле типа 90*M_PI или каждую итерацию в цикле считает заново?
Занялся сабжем по проекту. IDE Builder 2010 1) Оптимизирует ли компилятор выражения в цикле типа 90*M_PI или каждую итерацию в цикле...

Горят лампочки caps lock и num lock, ноутбук не включается
Доброе время суток, форумчане. Такая проблема, утром включаю ноутбук asus n53d, на нем одновременно загораются лампочки caps lock и num...

Условие в цикле
В таблице ADOTable6 есть поля AAA, SSS, XXX. Нужно пробежаться по таблице и в зависимости от значения поля AAA заполнить поле XXX. s -...

Условие в цикле
Здравствуйте. Почему в этом случае цикл выполняется девять раз: for(int year = 0; year &lt; 10; year++) А в этом десять: for(int...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru