Re[9]: Работа с потоками в C#. Часть 1.
От: Максим Зелинский  
Дата: 31.05.07 09:58
Оценка: +1
Здравствуйте, rsn81, Вы писали:

R>Здравствуйте, tol05, Вы писали:


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

Разве? Всегда считал, что атомарность значит "нераздельно". В плане команд это значит, что атомарную инструкцию будет выполнять всегда один поток. Просто если операция обернута в lock, то тогда да, данные будут сбрасываться
... << RSDN@Home 1.2.0 alpha rev. 679>>
Re[6]: Работа с потоками в C#. Часть 1.
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 31.05.07 10:01
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Грабли в этом переприсвоении читателю предлагается найти самому ;о)

Я глупый, объясните мне, что плохого?
Намекаете, что при выходе из lock блокировка с "потерянного" объекта не снимется? Не верю, а MSVS нет под рукой проверить... Это точно так?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[10]: Работа с потоками в C#. Часть 1.
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 31.05.07 10:05
Оценка:
Здравствуйте, Максим Зелинский, Вы писали:

Ага, не прав, бес попутал.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[10]: Работа с потоками в C#. Часть 1.
От: Mika Soukhov Stock#
Дата: 31.05.07 10:06
Оценка: +1
Здравствуйте, Максим Зелинский, Вы писали:

МЗ>Разве? Всегда считал, что атомарность значит "нераздельно". В плане команд это значит, что атомарную инструкцию будет выполнять всегда один поток.


Вроде как все инструкции атомарны. Или ты про операции?
Re[11]: Работа с потоками в C#. Часть 1.
От: Максим Зелинский  
Дата: 31.05.07 10:09
Оценка:
Здравствуйте, Mika Soukhov, Вы писали:

MS>Здравствуйте, Максим Зелинский, Вы писали:


МЗ>>Разве? Всегда считал, что атомарность значит "нераздельно". В плане команд это значит, что атомарную инструкцию будет выполнять всегда один поток.


MS>Вроде как все инструкции атомарны. Или ты про операции?

Да, операции
... << RSDN@Home 1.2.0 alpha rev. 679>>
Re[9]: Работа с потоками в C#. Часть 1.
От: tol05  
Дата: 31.05.07 10:13
Оценка:
Здравствуйте, Максим Зелинский, rsn81, вы писали:
(вы извините, но я не хочу раздувать ветки темы и в одной теме хочу задать вопрос обоим вам ) Но меня эта тема заинтересовала и я буду рад, если вы мне, все же ответите.

Максим Зелинский, вы писали:
МЗ>Не смешивайте. Проблемы с кэшем решаются через volitale и ему подобные конструкции, а блокировать ли на чтение, это уже другой вопрос, не имеющий отношение к кэшу.

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

Я не большой специалист в этой области и могу ошибаться... Мне непонятно, почему Вы, считаете, что блокировка на чтение не имеет значение к кешу? Ведь при работающем кешировании данные будут считываться из памяти только в первый раз, а во второй — браться из кеша?

rsn81, вы писали:
R>Атомарность операции и означает, что после ее выполнения данные будут доступны всем потокам, т.е. не будут находиться в регистрах, локальном кэше процессора и т.п.
Спасибо за ответ. Допустим, я в данный момент пишу вам ответ на двухпроцессорной машине. Чем сейчас (без введения дополнительных программных конструкций) обеспечиваетя атомарность операций над моимим данными?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Работа с потоками в C#. Часть 1.
От: tol05  
Дата: 31.05.07 10:14
Оценка:
Все, спасибо, читаю ответы Синхронизирую данные

T>rsn81, вы писали:

R>>Атомарность операции и означает, что после ее выполнения данные будут доступны всем потокам, т.е. не будут находиться в регистрах, локальном кэше процессора и т.п.
T>Спасибо за ответ. Допустим, я в данный момент пишу вам ответ на двухпроцессорной машине. Чем сейчас (без введения дополнительных программных конструкций) обеспечиваетя атомарность операций над моимим данными?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Работа с потоками в C#. Часть 1.
От: Sinclair Россия https://github.com/evilguest/
Дата: 31.05.07 10:18
Оценка: 25 (5)
Здравствуйте, rsn81, Вы писали:

R>Здравствуйте, _FRED_, Вы писали:


_FR>>Грабли в этом переприсвоении читателю предлагается найти самому ;о)

R>Я глупый, объясните мне, что плохого?
R>Намекаете, что при выходе из lock блокировка с "потерянного" объекта не снимется? Не верю, а MSVS нет под рукой проверить... Это точно так?
Это точно не так.
Но зато сразу после переприсвоения, еще до отпускания старого лока, другой поток сможет легко войти в защищенную lock-ом зону, т.к. будет блокироваться на другом объекте.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Работа с потоками в C#. Часть 1.
От: .Den Украина  
Дата: 31.05.07 10:49
Оценка:
Здравствуйте, Mika Soukhov:

Пример с lock:
1. Вычитывание из i
2. Инкримент
3. Запись в i
4. Присваивание 123 в i
результат i == 123
или
1. Присваивание 123 в i
2. Вычитывание из i
3. Инкримент
4. Запись в i
результат i == 124

Без lock:
1. Вычитывание из i
2. Присваивание 123 в i
3. Инкримент
4. Запись в i
или
1. Вычитывание из i
2. Инкримент
3. Присваивание 123 в i
4. Запись в i
результат i == 123
или любой из вышеприведенных случаев (результат 123 либо 124).
Чем здесь lock помогает на присваивании? 100% тратятся зря ресурсы, толку ровно ноль. Пример неудачный.
Re[5]: Работа с потоками в C#. Часть 1.
От: .Den Украина  
Дата: 31.05.07 10:53
Оценка:
Здравствуйте, Mika Soukhov, Вы писали:

MS>

MS>Как правило, любое поле, доступное нескольким потокам, должно читаться и записываться с блокировкой. Даже в самом простом случае, операции присваивания одиночному полю, необходима синхронизация. В следующем классе ни приращение, ни присваивание не потокобезопасны:


MS>Выделенное — неправильно. Но на удивление, сам пример корректен.

Пример на столько же корректен, как был бы и без lock в присваивании.
Re[6]: Работа с потоками в C#. Часть 1.
От: Mika Soukhov Stock#
Дата: 31.05.07 11:51
Оценка:
Здравствуйте, .Den, Вы писали:

D>Здравствуйте, Mika Soukhov:


D>Пример с lock:

D>1. Вычитывание из i
D>2. Инкримент
D>3. Запись в i
D>4. Присваивание 123 в i
D>результат i == 123
D>или
D>1. Присваивание 123 в i
D>2. Вычитывание из i
D>3. Инкримент
D>4. Запись в i
D>результат i == 124

D>Без lock:

D>1. Вычитывание из i
D>2. Присваивание 123 в i
D>3. Инкримент
D>4. Запись в i
D>или
D>1. Вычитывание из i
D>2. Инкримент
D>3. Присваивание 123 в i
D>4. Запись в i

1. Присваивание 123 в i
2. Вычитывание из i
3. Присваивание 123 в i
4. Инкримент
5. Присваивание 123 в i
6. Запись в i

D>результат i == 123

D>или любой из вышеприведенных случаев (результат 123 либо 124).

Вариантом поведения больше. Чем в программе больше вариантов, тем меньше у программиста желание это мейнтейнить.

D>Чем здесь lock помогает на присваивании? 100% тратятся зря ресурсы, толку ровно ноль. Пример неудачный.


Может. Статья то явно уровня 200. Так что может и лучше, что все так просто и примитивно.
Re[8]: Работа с потоками в C#. Часть 1.
От: Mika Soukhov Stock#
Дата: 31.05.07 11:54
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, rsn81, Вы писали:


R>>Здравствуйте, _FRED_, Вы писали:


_FR>>>Грабли в этом переприсвоении читателю предлагается найти самому ;о)

R>>Я глупый, объясните мне, что плохого?
R>>Намекаете, что при выходе из lock блокировка с "потерянного" объекта не снимется? Не верю, а MSVS нет под рукой проверить... Это точно так?
S>Это точно не так.
S>Но зато сразу после переприсвоения, еще до отпускания старого лока, другой поток сможет легко войти в защищенную lock-ом зону, т.к. будет блокироваться на другом объекте.

Я даже более могу сказать. В лок можно передавать объекты велью типов . Эдакий подход распараллеливания процессов. Надо вводить женерик тип лока.
Re[7]: Работа с потоками в C#. Часть 1.
От: .Den Украина  
Дата: 31.05.07 11:58
Оценка:
Здравствуйте, Mika Soukhov, Вы писали:

MS>1. Присваивание 123 в i

MS>2. Вычитывание из i
MS>3. Присваивание 123 в i
MS>4. Инкримент
MS>5. Присваивание 123 в i
MS>6. Запись в i

Ну так напиши как изменится результат с использованием lock'а??

1. Присваивание 123 в i
3. Присваивание 123 в i
3. Присваивание 123 в i
2. Вычитывание из i
4. Инкримент
6. Запись в i

Будет ли такое поведение по-другому отражено в значении переменной?
Re[9]: Работа с потоками в C#. Часть 1.
От: Кэр  
Дата: 31.05.07 12:08
Оценка:
Здравствуйте, Mika Soukhov, Вы писали:

MS>Я даже более могу сказать. В лок можно передавать объекты велью типов . Эдакий подход распараллеливания процессов. Надо вводить женерик тип лока.


Надо ли? Так или иначе lock работает через object. К object можно привести что угодно
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Работа с потоками в C#. Часть 1.
От: Mika Soukhov Stock#
Дата: 31.05.07 12:09
Оценка:
Здравствуйте, rsn81, Вы писали:

R>

Безопасность инициализации

R>Новая модель памяти JMM также старается предоставить новые гарантии безопасности инициализации. То есть, если объект соответствующим образом сконструирован (то есть ссылка на объект не опубликована, пока конструирование не завершено), тогда все потоки будут видеть значения его полей final, которые были установлены конструктором, независимо от того, используется ли синхронизация, чтобы передать ссылку из одного потока другому. Более того, переменные, которые могут быть доступны через поле final должным образом сконструированного объекта, например поля объекта, на который ссылается поле final, также гарантированно видимы другим потокам. Это значит, что если поле final содержит ссылку на, скажем, LinkedList, кроме видимости правильного значения ссылки другим потокам, содержимое этого LinkedList во время конструирования будет доступно другим потокам без синхронизации. Результат этого — значительное усиление значения final, то есть поля final могут быть безопасно доступны без синхронизации, и компиляторы могут предположить, что поля final не изменятся, и следовательно смогут оптимизировать множественные выборки.


Сразу скажу, что ничего практически не понял, кроме последнего. В .NET насколько я могу предполагать оптимизируются только константы (вшиваются прямо в код, без обращения по адресу). Readonly поля на самом деле можно изменять, но только через reflection.

Если я ответил на твой вопрос — я рад.
Re[9]: Работа с потоками в C#. Часть 1.
От: tol05  
Дата: 31.05.07 12:11
Оценка:
Здравствуйте, Mika Soukhov, Вы писали:

MS>Я даже более могу сказать. В лок можно передавать объекты велью типов

А в чем тогда смысл лока? Value типы не имеют индекса синхронизации, как же один поток узнает, что переменная заблокирована другим потоком?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Работа с потоками в C#. Часть 1.
От: Mika Soukhov Stock#
Дата: 31.05.07 12:16
Оценка: +1
Здравствуйте, tol05, Вы писали:

T>Здравствуйте, Mika Soukhov, Вы писали:


MS>>Я даже более могу сказать. В лок можно передавать объекты велью типов

T>А в чем тогда смысл лока? Value типы не имеют индекса синхронизации, как же один поток узнает, что переменная заблокирована другим потоком?

Не знаю, что такое индекс синхронизации у Value типа, но смысла тут и нет. Аргумент каждый раз боксится, и в лок передается новый объект. Вообщем, рассматривай это как bad (maybe worst) practic.
Re[10]: Работа с потоками в C#. Часть 1.
От: Lloyd Россия  
Дата: 31.05.07 12:16
Оценка: +1
Здравствуйте, tol05, Вы писали:

MS>>Я даже более могу сказать. В лок можно передавать объекты велью типов

T>А в чем тогда смысл лока? Value типы не имеют индекса синхронизации,

в незабоксеном состоянии

T>как же один поток узнает, что переменная заблокирована другим потоком?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: Работа с потоками в C#. Часть 1.
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 31.05.07 13:53
Оценка:
Здравствуйте, Mika Soukhov, Вы писали:

MS>Сразу скажу, что ничего практически не понял, кроме последнего.

Речь про один аспект синхронизации, о котором многие и не думают, видимости. То есть если поток_1 производит вычисление переменной_1 в значение_1, как другой поток_2 увидит значение_1?

А причины, по которой поток_2 увидит в переменной_1 не значение_1, следующие. Компиляторы, среда выполнения и кэш обычно вправе перераспределять инструкции по своему усмотрению в сторону большей эффективности, если не рушится семантическая последовательность.

Термин переупорядочивание используется для описания нескольких классов реальных и очевидных перераспределений операций с памятью:


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

(с) из той же статьи

К примеру, в старой версии Java 1.3 такой пример мог выполнится не так, как задумывалось:

volatile boolean initialized = false;
// запретили initialized хранить в локальной памяти:
// кэши, регистры, аппаратные средства, оптимизация программы в процессе компилирования и т.п.
// и наивно надеемся, что все будет OK

// В потоке_1
HashMap config = new HashMap();
init(config);
initialized = true;

// В потоке_2
while (!initialized) 
    sleep();
// инициализация закончена, начинаем использовать config
config.get("someProperty"); // получаем null, что такое?

Дело в том, что раньше операциям записи не volatile-переменных позволялось быть перераспределенными с операцими записи volatile-переменных. В итоге, весьма возможна ситуация, когда initialized == true, но config еще не заполнен необходимыми данными. В последующих версиях перераспределение операций чтения-записи volatile-переменных с такими же операциями по другим переменным решили запретить — код приведенный выше стал исполняться гарантированно, правда, чуть медленнее.

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

MS>Если я ответил на твой вопрос — я рад.

Речь о том, что синхронизация это не только synchronized (lock в .NET), т.е. взаимное исключение, не дающее более чем одному объекту зайти в потокоопасный участок кода, но и правила видимости памяти: сброс кэш при выходе из synchronized-блока, объявление их недействительными при входе в него, запрет компилятору перемещать инструкции изнутри synchronized-блока наружу, правда, внутрь можно.

PS Еще раз повторюсь, так в Java, в .NET так детально не знаю, но подозреваю, что аналогично... Потому и заинтересовала данная статья и это обсуждение.
Re[11]: Работа с потоками в C#. Часть 1.
От: tol05  
Дата: 31.05.07 13:55
Оценка:
Здравствуйте, Mika Soukhov, Вы писали:

MS>Аргумент каждый раз боксится, и в лок передается новый объект. Вообщем, рассматривай это как bad (maybe worst) practic.


В том-то и дело, что переменная int myInt, требуемая двум потокам, не будет синхронизирована, ее упакованная копия синхронизируется. Но ведь пока один поток с переменной (вернее, с ее упакованным значением) работает в функции
f()
{
lock(this.myInt)
{
}
}

второй может это значение изменить несколькими вызовами
F1()
{
this.myInt += 10;
}

и что произойдет с this.myInt, когда первый поток закончит работу?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.