|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
У меня уже от постоянных фейспалмов при работе с .Net рука отвалится. Чем дальше в лес, тем хуже и хуже. Про кривизну с long, который нельзя объявить volatile, мы уже говорили. Теперь поговорим про локи. Они отвратительны. Хуже этого я ничего не видел. Итак, имеем ReadWriteLock и ReadWriteLockSlim. 1) Всем нормальным людям давным давно известно, что нельзя делать апгрейд с read lock до write lock. Это антипаттерн. Если вам это требуется - значит вы уже свернули не туда, значит у вас уже кривой дизайн. Поэтому в Java, например апгрейд делать нельзя - мы, джависты, не любим, кривоту. А что думают по этому поводу разработчики .Net? А им срать, они берут, и имплементируют апгрейд, и имплементируют его криво - что бы получить write lock все равно надо отпустить read lock. То есть это голимейший синтаксический сахар, который только усложняет код. Гомно. 2) Ну ладно, подглядели майкрософтовцы в AbstractQueuedSynchronizer в Java, и попытались заимплементировать новый rwlock, который пытается не лезть в операционку, и назвали его ReadWriteLockSlim. Но и здесь их не оставила идея фикс про апгрейд. И они ввели трейтий вид лока - upgradable read lock, который вроде бы уже и не read lock, ибо только один тред может его держать, но еще и не write lock. Но и он опять не решает классическую проблему апгрейда. Ведь если в read lock, то для получения upgradable lock вам надо сначала отпустить read lock. А если вы сразу берете upgradable lock, то другие потоки не смогут его взять. Как обычно - криво, через жопу, проблему не решили, но в API ввели. Гомно. 3) А что, если, например, мне достался legacy код, в котором используется ReadWriteLock, и я захотел его подтянуть под новые омдные тренды, и заменить его ReadWriteLockSlim? В Java Lock и ReadWriteLock - это интерфейсы, потому что разработчики JVM знают, что такое ООП, и в чем смысл фразы "code to interfaces". А в .Net таких итерфейсов нет, и если вы решили поменять RWLock на RWLockSlim, вам придется руками поменять абсолютно все вызовы этого метода. Ведь заботливые разработчики .Net подумали о нас: ReaderWriterLock.EnterRead er Lock() ReaderWriterLockSlim.EnterReadLock() И вы потом рассказываете миру, какой крутой и прогрессивный язык C#? Когда в нем нет ни одного нормального человеческого API? Коллекции - через жопу, но есть LINQ. Многопоточность - через жопу, но есть async/await. Сокеты - просто через жопу, без всяких "но", посмотрите ради интереса на API Java "Selector", и как в JVM нативно реализована операция select, а потом сравните это с убогим и неэффективным Socket.Select() в .Net. Я в ужасе :-( ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 00:49 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvПро кривизну с long, который нельзя объявить volatile, мы уже говорили. зачем тебе это? "Если вам это требуется - значит вы уже свернули не туда, значит у вас уже кривой дизайн." cdtyjv1) Всем нормальным людям давным давно известно, что нельзя делать апгрейд с read lock до write lock. Это антипаттерн. Если вам это требуется - значит вы уже свернули не туда, значит у вас уже кривой дизайн. Поэтому в Java, например апгрейд делать нельзя - мы, джависты, не любим, кривоту. А что думают по этому поводу разработчики .Net? А им срать, они берут, и имплементируют апгрейд, и имплементируют его криво - что бы получить write lock все равно надо отпустить read lock. То есть это голимейший синтаксический сахар, который только усложняет код. Гомно. Смотрим на upgradeable lock - http://msdn.microsoft.com/ru-ru/library/system.threading.readerwriterlockslim.enterupgradeablereadlock(v=vs.110).aspx Упс, не надо ничего опускать... cdtyjv2) Ну ладно, подглядели майкрософтовцы в AbstractQueuedSynchronizer в Java, и попытались заимплементировать новый rwlock, который пытается не лезть в операционку, и назвали его ReadWriteLockSlim. Но и здесь их не оставила идея фикс про апгрейд. И они ввели трейтий вид лока - upgradable read lock, который вроде бы уже и не read lock, ибо только один тред может его держать, но еще и не write lock. Но и он опять не решает классическую проблему апгрейда. Ведь если в read lock, то для получения upgradable lock вам надо сначала отпустить read lock. А если вы сразу берете upgradable lock, то другие потоки не смогут его взять. Как обычно - криво, через жопу, проблему не решили, но в API ввели. Гомно. Нет сценария reald lock -> upgradeable lock -> write lock и нет сценария read lock -> write lock. "Если вам это требуется - значит вы уже свернули не туда, значит у вас уже кривой дизайн." Это в Java есть сценарий read lock -> write lock, ибо нет upgradeable lock. И кроме как "через жопу" такой сценарий сделать нельзя, а в .NET можно. cdtyjv3) А что, если, например, мне достался legacy код, в котором используется ReadWriteLock, и я захотел его подтянуть под новые омдные тренды, и заменить его ReadWriteLockSlim? В Java Lock и ReadWriteLock - это интерфейсы, потому что разработчики JVM знают, что такое ООП, и в чем смысл фразы "code to interfaces". А в .Net таких итерфейсов нет, и если вы решили поменять RWLock на RWLockSlim, вам придется руками поменять абсолютно все вызовы этого метода. Ведь заботливые разработчики .Net подумали о нас: ReaderWriterLock.EnterRead er Lock() ReaderWriterLockSlim.EnterReadLock() В Java RWLock и RWLockSlim реализуют одни и те же сценарии. А в .NET ReaderWriterLock и ReaderWriterLockSlim - разные. В частности из-за наличия Upgradeable lock. Но именно из-за "code to interfaces" в Java вообще вообще существует "классическая проблема апгрейда", а в .NET её решили уже 8 лет назад. cdtyjvИ вы потом рассказываете миру, какой крутой и прогрессивный язык C#? Когда в нем нет ни одного нормального человеческого API? Коллекции - через жопу, но есть LINQ. Многопоточность - через жопу, но есть async/await. Сокеты - просто через жопу, без всяких "но", посмотрите ради интереса на API Java "Selector", и как в JVM нативно реализована операция select, а потом сравните это с убогим и неэффективным Socket.Select() в .Net. В .NET никто не использует Socket.Select, проще все делать через асинхронный код и async\await. cdtyjvЯ в ужасе :-( Это потому что ты паттерны Java пытаешься натянуть на .NET. Но чуваки из МС не дрочат на ООП и "code to interfaces", поэтому уже 10 раз придумали эффективные решения проблем, которые до сих пор в java решают как получится. Самое смешное: 1) За почти 10 лет в .NET не видел необходимости делать локи вручную, слишком это низкоуровневая вещь. Даже банальный lock(obj) многие лепят там, где он по сути не нужен. Многое уже реализовано в библиотеках, зачастую lock-free. 2) В нынешних условиях тотальной асинхронности в .NET обычные локи уже неактуальны, чаще используют синхронизацию задач через шедулеры и\или очереди. 3) Сокеты вручную довелось писать ровно один раз, потому что сервер был нативный и никаких стандартных протоколов не поддерживал. Для всего остального уже дофига всего напридумано - веб-сервисы, .net.tcp, webapi, signalr. Поэтому если требуется вызывать Socket.Select, то "Если вам это требуется - значит вы уже свернули не туда, значит у вас уже кривой дизайн." ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 03:13 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
gandjustasЗа почти 10 лет в .NET не видел необходимости делать локи вручную, слишком это низкоуровневая вещь gandjustasМногое уже реализовано в библиотеках, зачастую lock-free Полностью поддерживаю. Все прогрессивное человечество знает, что идеал многопоточной архитектуры - это lock-free model. Только Java-хардкодеры до сих пор колупаются с блокировками. cdtyjvКоллекции - через жопу, но есть LINQ С коллекциями все нормально, нужно не стесняться применять дженерики, а не впадать в маразм и использовать нетипизированные коллекции cdtyjvМногопоточность - через жопу, но есть async/await Забыли еще TPL. А про жопу - ну у кого откуда руки растут :-) cdtyjvСокеты - просто через жопу, без всяких "но", посмотрите ради интереса на API Java "Selector", и как в JVM нативно реализована операция select, а потом сравните это с убогим и неэффективным Socket.Select() в .Net. Забыл, вы ведь для своей системы в качестве конкурентного преимущества используете самописный протокол поверх udp. Ведь если это не так, то отказ от WCF с прикрученным для скорости Protocol Buffers выглядит совершенно неразумным решением. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 06:54 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv, Посочуствуйте и мне тоже. Я год на джаве писал. Нормального foreach цикла нету, двоеточия какие-то... Эклипса - глючная и тормознутая, только на 8 ядерном компе отжила и зашевелилась... Ну а уж про привязку неймспейсов жестко к файловой системе в джаве - я вообще молчу.... Нельзя оставить ненужный временно файл - надо его обязательно убивать, чтобы скажем, без него попробовать... В Студии можно включить в проэкт, исключить из проэкта..... А эта (в Эклипсе) необходимость учить всяки комбинации клавиш? чтобы закоментировать блок кода? а кнопочку сделать слабо? В Студии есть.... :-)))))))))))))))))))) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 10:19 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvЯ в ужасе :-(Что, Свеном, все сроки просрал? Ох, уволят тебя. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 10:24 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvЯ в ужасе :-( валерьянки выпей ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 10:59 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Очередной перл от .Net. Есть у меня generic-поле в классе. Я хочу его сделать волатильным. Окей, пробуем: volatile T obj; Нельзя, компилятор ругается, ведь как оказывается volatile можно ставить на дженерик только если "Generic type parameters known to be reference types." Это что за бред? int не является ссылочным типом, но его можно объявить volatile. А вот если есть вероятность, что за моим дженериком окажется этот же самый int - то все, криминал. Видимо, у этого маразма растут ноги с уже рассмотренного нами запрета объявлять volatile типы long и double. Окей, может быть тогда хотя бы так получится прочитать его волатильно: Код: c# 1.
Хрен там! Нет такого оверрайда. Ну а может быть хотя бы вот такой метод есть: Код: c# 1.
Не, пацанам из Microsoft, видимо, западло было его имплементировать. В итоге, что бы решить простейшую задачу волатильных чтений/записи дженерик-поля я должен брать, и реализовывать его волатильность руками: Код: c# 1. 2. 3. 4. 5. 6.
Слов просто нет. У меня есть адрес в памяти, я хочу прочитать его волатильно (или записать). Почему я не могу это сделать по человечески? Почему элементарную операцию надо обязательно делать через задницу? А, или вы мне сейчас опять начнете рассказывать, что нормальные пацаны volatile не используют? Когда казалось, что мы достигли дна, снизу постучались. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 14:45 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvvolatile не используют? Я не использовал. Блокировки нужны на уровне бизнеса обычно. за каким лешим синхронизировать только поля - я не имею представления. Это вы явно пытаетесь на шарпе сделать то, для чего он не предназначен. Типа нанооптимизация для повышения производительности? Что же вы эдакое делате, что микросекунды важны? Виндовс вообще не для подобных систем... Вот вы тут рубитесь, переменные блокируете, чтобы паралельно чего-нибудь посчитать (а для чего еще могут быть блокировки отдельных полей?) а винда раз! И квант времени вам не дала. Доктор ватсон какой нибудь запустился или еще что... И вся ваша нанооптимизация - профукала в тысячу раз больше (квант времени ведь аж 15 милисекунд - это очень много), чем сэкономить может. И зачем вы над этим мучались? А на уровне бизнеса да - лочишь критическую секцию, и все ок. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 15:19 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv, Мне ваши расследования напоминают как я один раз прочитал в английском тексте слово "squid". У меня был словарь (бумажный еще) и я его считал хорошим. Полез я искать это слово в словаре, и не нашел. Плохой словарь! После этого я так и проверял словари - есть перевод слова "кальмар" - хороший словарь.... Ну согласитесь - глупость ведь... ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 15:28 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvКогда казалось, что мы достигли дна, снизу постучались. Это произошло сразу, как свеном решил сесть за программирование. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 16:10 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvУ меня есть адрес в памяти, я хочу прочитать его волатильно (или записать) А зачем? Вы можете рассказать нам? Я вот искренне интересуюсь. Мне ни разу не приходилось использовать volatile. Может, я упустил какой то важный момент в изучении платформы? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 16:44 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Arm79cdtyjvУ меня есть адрес в памяти, я хочу прочитать его волатильно (или записать) А зачем?Свеному дали Java-код, сказали перевести на C#. А в Java-коде volatile. В итоге Свеном в ужасе. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 17:15 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
skyANAArm79пропущено... А зачем?Свеному дали Java-код, сказали перевести на C#. А в Java-коде volatile. В итоге Свеном в ужасе. Тогда он сейчас у начальства - обьясняет начальству бессмысленность нано-оптимизации. Получает разрешение отменить многопоточность... :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 17:24 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Arm79 Мне ни разу не приходилось использовать volatile. MSDNКак правило, модификатор volatile используется для поля, обращение к которому выполняется из нескольких потоков без использования оператора lock для сериализации доступа. Например флаг какой пометить. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 17:26 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
ЕвгенийВArm79 Мне ни разу не приходилось использовать volatile. MSDNКак правило, модификатор volatile используется для поля, обращение к которому выполняется из нескольких потоков без использования оператора lock для сериализации доступа. Например флаг какой пометить. Ну допустим флаги типа bool, int и т.п. не нуждаются в дополнительной синхронизации, тк операции чтения/записи являются атомарными. Если, конечно, не писать c = a + b + с. Я по возможности стараюсь не разделять данные между потоками. А те немногие случаи, когда все-таки нужно анализировать флаги, использую Interlocked Как-то так, по простому, без изысков. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 17:41 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Arm79Ну допустим флаги типа bool, int и т.п. не нуждаются в дополнительной синхронизации, тк операции чтения/записи являются атомарными. операции то атомарные, а вот изменение последовательности выполнения компилятором, а затем процессором может стать фатальным. volatile -это от этой болезни лекарство ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 18:53 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Изопропилоперации то атомарные, а вот изменение последовательности выполнения компилятором, а затем процессором может стать фатальным. volatile -это от этой болезни лекарство Как-то ни разу не встречалась такая ситуация, хотя я много лет именно многопоточку пишу :). Ну, посмотрим, может и пригодится... ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 18:57 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvОчередной перл от .Net. Есть у меня generic-поле в классе. Я хочу его сделать волатильным. Начинай изучать отсюда http://blogs.msdn.com/b/ericlippert/archive/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three.aspx Потом тут: http://joeduffyblog.com/2010/12/04/sayonara-volatile/ Не надо тебе ничего делать волатильным, ибо ты даже не понимаешь что это значит. "Если вам это требуется - значит вы уже свернули не туда, значит у вас уже кривой дизайн." (с) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 19:32 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
D129Это вы явно пытаетесь на шарпе сделать то, для чего он не предназначен. Типа нанооптимизация для повышения производительности? Хз что товарищ пытается сделать, но по производительности получит результат от его действий будет ровно обратный. D129А на уровне бизнеса да - лочишь критическую секцию, и все ок. А как же асинхронность? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 19:34 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
ЕвгенийВArm79 Мне ни разу не приходилось использовать volatile. MSDNКак правило, модификатор volatile используется для поля, обращение к которому выполняется из нескольких потоков без использования оператора lock для сериализации доступа. Например флаг какой пометить. volatile не сериализует доступ, в MSDN не точное описание. volatile не является средством синхронизации для многопроцессорных компьютеров. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 19:41 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
gandjustasD129А на уровне бизнеса да - лочишь критическую секцию, и все ок. А как же асинхронность? А бывает что ресурс уникальный. Конкретно писал поиск наилучшей полки. Когда находим - помечаем, занято. Другие вызовы этого же сервиса (ну в случае многих вьездов в склад, и тп) - ставим в очередь, Чтобы не отправить реальных два ящика на одну и ту же полку. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 20:29 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Arm79Как-то ни разу не встречалась такая ситуация, хотя я много лет именно многопоточку пишу :). Ну, посмотрим, может и пригодится...Вынужден вас огорчить - вы не пишете "многопоточку". Возможно, вы думаете, что пишете ее, но это не так. Ибо непонимание volatile означает непонимание самых основ того, как потоки взаимодействуют друг с другом. Я допускаю, что вы пишете приложения, которые работают в многопоточном окружении, но, наверняка, вся многопоточность разруливается каким-нибудь фреймворком, вроде ASP.NET. То есть вы не пишете многопоточный код. Вы пишете однопоточный код, который благодаря счастливому стечению обстоятельств нормально работает в многопоточной среде. А это разные вещи. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 20:35 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
D129Это вы явно пытаетесь на шарпе сделать то, для чего он не предназначен. Типа нанооптимизация для повышения производительности?То есть все то, что делает Microsoft - говно? Все эти Active DIrectory, SQL Server, и т.д. - все это обречено быть медленным? Это глупость. На винде можно писать нормальные скоростные приложения. D129Что же вы эдакое делате, что микросекунды важны? Виндовс вообще не для подобных систем... Вот вы тут рубитесь, переменные блокируете, чтобы паралельно чего-нибудь посчитать (а для чего еще могут быть блокировки отдельных полей?) а винда раз! И квант времени вам не дала. Доктор ватсон какой нибудь запустился или еще что... И вся ваша нанооптимизация - профукала в тысячу раз больше (квант времени ведь аж 15 милисекунд - это очень много), чем сэкономить может. И зачем вы над этим мучались?Не пишите бред. В промышленных деплойментах с развернутыми приложениями, время отклика которых критично, никакой Доктор Ватсон не может ВНЕЗАПНО запуститься по определению. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 20:40 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv В промышленных деплойментах с развернутыми приложениями, время отклика которых критично, никакой Доктор Ватсон не может ВНЕЗАПНО запуститься по определению. Скорость выполнения в виндовс - это вероятность. Если нагрузка низкая, то вероятность того, что будет выполняться только одна аппликация, раз за разром получая кванты - высока. Но в любом случае, наступит момент, когда эта аппликация квант не получит, будет пропуск в работе 15 милисекунд (зависит от величины кванта конкретной машины) - и все продолжится. Многоядерность добавляет вероятности, что квант времени будет чаще выделяться. Да, все продукты майкрософт - обречены быть "не предназначены для систем реального времени" - так в записано в документе, который никто не читает. :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 20:46 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvArm79Как-то ни разу не встречалась такая ситуация, хотя я много лет именно многопоточку пишу :). Ну, посмотрим, может и пригодится...Вынужден вас огорчить - вы не пишете "многопоточку". Возможно, вы думаете, что пишете ее, но это не так. Ибо непонимание volatile означает непонимание самых основ того, как потоки взаимодействуют друг с другом. Я допускаю, что вы пишете приложения, которые работают в многопоточном окружении, но, наверняка, вся многопоточность разруливается каким-нибудь фреймворком, вроде ASP.NET. То есть вы не пишете многопоточный код. Вы пишете однопоточный код, который благодаря счастливому стечению обстоятельств нормально работает в многопоточной среде. А это разные вещи. Смешно :-) Но я опровергать не собираюсь. Те, кто знает меня, понимают, что это ерунда, те, кто не знает - ну мне их мнение неинтересно. Тем не менее, я так от вас и не услышал, в каком конкретно кейсе вы вынуждены применить volatile? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 21:20 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Arm79в каком конкретно кейсе вы вынуждены применить volatile? 16353282 ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 21:24 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
skyANAArm79в каком конкретно кейсе вы вынуждены применить volatile? 16353282 Хватит издеваться :-) Я серьезно спрашиваю. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 21:31 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
gandjustasvolatile не сериализует доступ, в MSDN не точное описание. volatile не является средством синхронизации для многопроцессорных компьютеров. да, это так. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 22:07 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Изопропилgandjustasvolatile не сериализует доступ, в MSDN не точное описание. volatile не является средством синхронизации для многопроцессорных компьютеров. да, это так.Нет, это не так. volatile и сериализует доступ к конкретной переменной (напр. к long на 32-битной платформе), и является примитивом синхронизации благодаря окружающим его барьерам памяти. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 22:12 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvНет, это не так. volatile и сериализует доступ к конкретной переменной (напр. к long на 32-битной платформе), и является примитивом синхронизации благодаря окружающим его барьерам памяти. Ты вообще не понимаешь что такое volatile . Может хоть один букварь откроешь наконец, а? Выглядишь глупо, честно. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 22:26 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
D129gandjustasпропущено... А как же асинхронность? А бывает что ресурс уникальный. Конкретно писал поиск наилучшей полки. Когда находим - помечаем, занято. Другие вызовы этого же сервиса (ну в случае многих вьездов в склад, и тп) - ставим в очередь, Чтобы не отправить реальных два ящика на одну и ту же полку. Interlocked.CompareExchange не? Это если данные в памяти, а если это база, то уникальный индекс на (полка, место). ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 22:55 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
hVosttТы вообще не понимаешь что такое volatile . Может хоть один букварь откроешь наконец, а? Выглядишь глупо, честно.Хм, то есть volatile не гарантирует атомарность записи, и вокруг него нет барьеров? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 22:55 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvХм, то есть volatile не гарантирует атомарность записи, и вокруг него нет барьеров? Я ещё раз настоятельно рекомендую открыть букварь и почитать: 1. Что делает модификатор volatile 2. Как это связано с архитектурой процессора, на котором будет исполняться приложение 3. Зачем нужен и когда применяется volatile 4. Какие даёт гарантии volatile , а каких гарантий он не даёт Когда разберёшься, у тебя все вопросы сразу отпадут по поводу того, почему принципиально и технически в среде .NET (на сегодняшний день) нельзя объявить volatile long и double . Ты отчётливо поймёшь почему. И поймёшь, что на месте разработчиков ты бы сделал также. Возможно ты тупо наезжаешь на синтаксис и обижаешься на то, почему в C# нельзя было сделать ключевое слово volatile «синтаксическим сахаром», который бы придавал «волатильности» чему угодно. Я бы понял такой наезд в отношение VisualBasic.NET, но никак не для C#, который часто применяется для написания высоконагруженных приложений, где volatile должен быть именно тем, чем он на самом деле является, а не каким-то «сахаром» в угоду всяким раздолбаям типо тебя ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:22 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv, В конце концов открой уже для себя Volatile из .NET 4.5 и не выкалупывай форумчанам мозг на ровном месте. Можешь даже состряпать свой struct CdtyjvVolatile<T>, ведь платформа даёт тебе все карты в руки. Действуй! ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:32 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv, летучесть это фишка записи и чтения данных процессора в контексте его кеша( процессора), если два разных потока крутятся на разных ядрах , работат с переменными оптимизирована через кеш каждого процессора, то есть фактическое изменение переменной задерживается в кеше, а если оно задерживается то второе ядро не может получить реальное значение. volatile дает команду процессору изменить значение переменной минуя ее копию в кеше ( сквозное изменение) и автоматом объявляет кеш не действительным - отсюда и вся гадость со скоростью доступа к кешу ядра ( приходится опять заныривать в оперативку). ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:33 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
hVosttКогда разберёшься, у тебя все вопросы сразу отпадут по поводу того, почему принципиально и технически в среде .NET (на сегодняшний день) нельзя объявить volatile long и double . Ты отчётливо поймёшь почему. И поймёшь, что на месте разработчиков ты бы сделал также.А вы не можете мне ответить на этот вопрос? Почему нельзя? Вот я работаю в 64-битной среде, у меня есть ссылка, она занимает 8 байт. Ее можно объявить volatile. Вот я работаю в 64-битной среде, и у меня есть long. Ее нельзя объявить volatile. Но при этом у меня есть Thread.VolatileRead(ref long), где long все таки можно читать/писать как volatile, вне зависимости от того, сижу я в 64-битной или 32-битной среде. Что я не понимаю? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:36 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Где-то в степи, как ни печально, эти рассуждения к архитектуре x86/64 отношения не имеют ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:37 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvНо при этом у меня есть Thread.VolatileRead(ref long вскрытие показывает, что на 32 бит он не атомарен. селяви ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:39 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Где-то в степиcdtyjv, летучесть это фишка записи и чтения данных процессора в контексте его кеша( процессора), если два разных потока крутятся на разных ядрах , работат с переменными оптимизирована через кеш каждого процессора, то есть фактическое изменение переменной задерживается в кеше, а если оно задерживается то второе ядро не может получить реальное значение. volatile дает команду процессору изменить значение переменной минуя ее копию в кеше ( сквозное изменение) и автоматом объявляет кеш не действительным - отсюда и вся гадость со скоростью доступа к кешу ядра ( приходится опять заныривать в оперативку).Ну вы совершенно не правы. volatile переменные сидят в кэше так же, как и все остальные. Они отличаются от обычных переменныъ только двумя вещами: 1) Компилятору запрещено оптимизирвоать доступ к ним. То есть, если у меня в коде идет два чтения volatile, то register allocator компилятора не может прочитать ее один раз, сохранить в регистр, а второй раз прочитать копию из него. Он обязан дважда обратиться в подсистему памяти (а подсистема памяти - это кэщ + оперативка, процессор их не отличает друг от друга). 2) Вокруг доступов к волатильным переменным выставляют барьеры, которые гарантируют синхронизацию кэшей разных ядер. Не то, что "переменная будет прочитана из памяти, а не из кэша" - это распространенное заблуждение. А то, что на записи волатиля ядро сбросит store buffer своего кэша в кэши других ядер, я чтение волатиля сначала обработает invalidate queue своего ядра, и лишь потом ее прочитает (либо из памяти, либо из кэша другого ядра через механизм snooping'а). ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:41 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvНо при этом у меня есть Thread.VolatileRead(ref long), где long все таки можно читать/писать как volatile, вне зависимости от того, сижу я в 64-битной или 32-битной среде. Что я не понимаю? Разницу не понимаешь между определением и операцией. Модификатор volatile инструктирует компилятор избегать оптимизации при работе с переменной. Любой код, который использует эту переменную, не будет оптимизирован в отношение этой переменной. А конкретно ты можешь «волатильно» прочитать и записать любой тип. Сравнивать размеры ссылки и long -- вообще не уместно, так как размер long всегда 64 бита. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:45 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Изопропилвскрытие показывает, что на 32 бит он не атомарен. селяви Свеном полагает, что если он работает на x64, то никаких других систем в мире не существует. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:47 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvОн обязан дважда обратиться в подсистему памяти (а подсистема памяти - это кэщ + оперативка, процессор их не отличает друг от друга). Атомарности при этом отнюдь не гарантируется. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:51 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
ИзопропилcdtyjvНо при этом у меня есть Thread.VolatileRead(ref long вскрытие показывает, что на 32 бит он не атомарен. селявиДа, действительно. Зато атомарен Interlocked. Еще бОльшая кривота .Net'а. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:53 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvВокруг доступов к волатильным переменным выставляют барьеры Вот где твой косяк в отношении понимания модификатора volatile и «волатильным» чтением/записью. И ещё, кажется, что ты путаешь volatile с Interlocked , последний гарантирует атомарность операции, в то время как volatile — отнюдь не гарантирует. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:57 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvДа, действительно. Зато атомарен Interlocked. Еще бОльшая кривота .Net'а. Это не кривота, а элементарная безграмотность с твоей стороны. volatile и не должен обеспечивать атомарность, хотя ты почему-то решил иначе. Интересно, почему? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.07.2014, 23:59 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv, авторvolatile переменные сидят в кэше так же, как и все остальные ну сидят в кеше, вам то от этого чем легче, при записи происходит изменение переменной в кеше с последующим сбросом в основную память и объявлением последнего не действительным, считайте это за сквозную запись, в чем проблем, это уже детали чтение происходит обычным образом из кеша, то что оно не кешируется в регистрах, так это ежу понятно почему, атомарность на уровне железа никакой магии.. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:04 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv, На всякий случай, одно из классических применений volatile , это когда поток 1 изменяет переменную, а поток 2 читает, при этом не обеспечивается 100% гарантия актуального значения переменной в один и тот же момент времени. При этом, если не использовать volatile , поток 2 может так и не увидеть изменений, или получать совсем не актуальное значение. Для синхронизации потоков, volatile категорически не используется, как и «волатильные» чтение/запись. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:08 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
hVosttcdtyjv, На всякий случай, одно из классических применений volatile , это когда поток 1 изменяет переменную, а поток 2 читает, при этом не обеспечивается 100% гарантия актуального значения переменной в один и тот же момент времени. При этом, если не использовать volatile , поток 2 может так и не увидеть изменений, или получать совсем не актуальное значение. Для синхронизации потоков, volatile категорически не используется, как и «волатильные» чтение/запись.Угу, не используется. Например, вот здесь это не используется http://referencesource.microsoft.com/#mscorlib/system/threading/SpinLock.cs Все современные синхронайзеры, будь то ReentrantReadWriteLock в Java или какой-нибудь ReaderWriteLockSlim в Net ( http://reflector.webtropy.com/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/Core/System/Threading/ReaderWriterLockSlim/ReaderWriterLockSlim@cs/1305376/ReaderWriterLockSlim@cs)]http://reflector.webtropy.com/default.aspx/4@0/4@0/untmp/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/Core/System/Threading/ReaderWriterLockSlim/ReaderWriterLockSlim@cs/1305376/ReaderWriterLockSlim@cs) используют volatile/interlocked для попытки быстрого захвата ресурса, читай - быстрого занятия критической секции. А если это не получается, то они идут в ОС, и просят ее о помощи. По слову futex погуглите - та же самая концепция. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:17 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
hVosttВот где твой косяк в отношении понимания модификатора volatile и «волатильным» чтением/записью. И ещё, кажется, что ты путаешь volatile с Interlocked , последний гарантирует атомарность операции, в то время как volatile — отнюдь не гарантирует.Да, так и есть. Просто криворукие разработчики .Net решили не давать гарантии атомарности long/double, из-за чего и возник весь сыр-бор с невозможностью объявить их volatile, а оттуда же выросли проблемы с дженериками, которые так же нельзя объявить волатилями. Одно тупое решение какого-то неквалифицированного индуса, и API .Net превратился в гомно. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:19 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Где-то в степину сидят в кеше, вам то от этого чем легче, при записи происходит изменение переменной в кеше с последующим сбросом в основную память и объявлением последнего не действительнымЭто неправда. Тактика процессора в одношении "сброса" данных из кэшей в память относительно волатильных и неволатильных переменных одинакова. Это следуте из того простого факта, что если вы посмотрите на соответствующий ассемблерный код, то увидите, что и обычная запись, и волатиьлная - это просто инструкция mov. Нет способа сказать процессору, что это волатиьлная переменная, а эта нет. Он их не отличает. Но вокруг волатильных переменных компилятор добавляет барьеры (например, cmpxchg), которые гарантируют частичную синхронизацию состяний кешей между собой, а не между кэшем и памятью. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:22 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvИзопропилпропущено... да, это так.Нет, это не так. volatile и сериализует доступ к конкретной переменной (напр. к long на 32-битной платформе), и является примитивом синхронизации благодаря окружающим его барьерам памяти. Покажи код где этот "примитив синхронизации" таки синхронизирует доступ двух потоков к одним и тем же данным. Сериализация доступа к переменным не дает вообще ничего. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:23 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvДа, так и есть. Просто криворукие разработчики .Net решили не давать гарантии атомарности long/double, из-за чего и возник весь сыр-бор с невозможностью объявить их volatile, а оттуда же выросли проблемы с дженериками, которые так же нельзя объявить волатилями. Одно тупое решение какого-то неквалифицированного индуса, и API .Net превратился в гомно. Операции с: volatile int a; Точно также не атомарны. Ради всех цвятых, открой букварь и почитай. Зачем демонстрировать безграмотность? Открыл, почитал, всё понял, закрыл, поумнел = больше не говоришь глупостей. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:24 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvЧто я не понимаю? То что волатильность доступа не дает ничего с точки зрения синхронизации потоков. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:25 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvиспользуют volatile / Interlocked для попытки быстрого захвата ресурса нельзя можно использовать для захвата ресурсов. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:26 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv, Да ты даже в Java, как оказывается, ни черта не петришь. JEREMY MANSONIf a variable is declared as volatile, it means that it is expected to be modified by multiple threads. Naturally, you would expect the JRE to impose some form of synchronization for volatile variables. As luck would have it, the JRE does implicitly provide synchronization when accessing volatile variables, but with one very big caveat: reading a volatile variable is synchronized and writing to a volatile variable is synchronized, but non-atomic operations are not . What this means is that the following code is not thread safe : Код: java 1.
The previous statement could also be written as follows: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
In other words, if a volatile variable is updated such that, under the hood, the value is read, modified, and then assigned a new value, the result will be a non-thread-safe operation performed between two synchronous operations. You can then decide whether to use synchronization or rely on the JRE's support for automatically synchronizing volatile variables. The better approach depends on your use case: If the assigned value of the volatile variable depends on its current value (such as during an increment operation), then you must use synchronization if you want that operation to be thread safe . ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:35 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvУгу, не используется. Например, вот здесь это не используется http://referencesource.microsoft.com/#mscorlib/system/threading/SpinLock.cs Синхронизация обеспечивается не волатильностью, а interlocked - атомарными операциями. И это не одно и тоже. Волатильность нужна чтобы разные процессоры не считали что у одно и того же лока в один и тот же момент времени разные владельцы. Причем если убрать "владельца", то можно синхронизацию запилить и без volative (получится классический lock-free). ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:35 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvhVosttВот где твой косяк в отношении понимания модификатора volatile и «волатильным» чтением/записью. И ещё, кажется, что ты путаешь volatile с Interlocked , последний гарантирует атомарность операции, в то время как volatile — отнюдь не гарантирует.Да, так и есть. Просто криворукие разработчики .Net решили не давать гарантии атомарности long/double, из-за чего и возник весь сыр-бор с невозможностью объявить их volatile, а оттуда же выросли проблемы с дженериками, которые так же нельзя объявить волатилями. Одно тупое решение какого-то неквалифицированного индуса, и API .Net превратился в гомно. Это не тот же индус, котрый придумал AtomicInteger в Java? http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:44 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Ладно, с кривотой volatile я разобрался. Причина: какой-то индус-студент, пришедший в Microsoft набраться опыта, решил не давать гарантии атомарности чтений/записей типам long/double, хотя это сделать эелментарно (хотя бы просто делеировать в Interlocked). Потом через какое-то время появились дженерики, за которыми могли стоять все те же long и double. Но вместо того, что бы снять это ограничение (а из-за этого legacy код бы совершенно не пострадал), другой индус-студен решил запретить volatile и для дженериков. Из-за этого мы имеем кривой и косой API. Проехали. Следующая кривота. ThreadPool. Такого маразма я давно не видел: 1) Какой идиот решил сделать его общим на все приложение? Что он курил? 2) И зачем он смешал воедино обычныйе треды-воркеры и треды для completion ports? 3) И почему он не дал нам возможность нормально сконфигурировать его? Теперь расскажите мне, господа дотнетовцы, как вы будете решать следующие задачи с помощью этого уродца: 1) У вас в приложении генерируются задачи, которые надо выполнять последовательно одну за другой по мере их появления (примерно как это сделано с UI). Как вы этого будете делать? В Java я могу создать отдельный тред пул с ровно одним потоком, и класть в него задачи. Одна строчка кода. В .Net мне надо изобретать свой велосипед с while-циклами, блокирующими колелкциями и прочим дерьмом, которое характерно для тред-пулов. 2) Вы делаете нечто вроде map-reduce фреймворка. Пользователь дает вам задачи, вы их кладете в тред-пул. Каждая задача может сгенерировать другие задачи, которые пойдут в этот же тред-пул, и т.д.. Но кроме пользовательских задач, у вашего приложения еще есть свои системные задачи, которые должны быть гарантированно исполнены и исполнены быстро. Вопрос на засыпку - сможете ли вы использовать ThreadPool в этом случае? Хрен вам, господа! Ведь если юзерские задачи засрут вам пул, то время выполнения вашей системной задачи будет расти пропорционально размеру очереди пользовательских задач. И опять - пищем свои велосипеды. А в Java надо просто создать два разных пула - один для пользователей, один для себя. И все. Очередному индусу в программистском угаре пришла в голову идея сделать ThreadPool статическим, и все - вся идея тут же становится ограниченной и корявой. А надо то было просто конструкторик ThreadPool сделать публичным, что бы разработчики могли создавать свои пулы. Пару строчек кода поленились добавить. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:45 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv, А расскажи честно, зачем тебе volatile вообще понадобился? Пример кода приведи. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:48 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv, автор Он их не отличает я Вы что то мне приписываете, я где то сказал что это особая инструкция? авторкоторые гарантируют частичную синхронизацию состояний кешей между собой вот про это поподробней расскажите пож. если вы про MemoryBarrier то это фактический сброс кеша с последующим объявлением его не действительным- вот и вся синхронизация, или там есть еще какое то шаманство? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 00:49 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjvЛадно, с кривотой volatile я разобрался. Причина: какой-то индус-студент, пришедший в Microsoft набраться опыта, решил не давать гарантии атомарности чтений/записей типам long/double, хотя это сделать эелментарно (хотя бы просто делеировать в Interlocked). Потом через какое-то время появились дженерики, за которыми могли стоять все те же long и double. Но вместо того, что бы снять это ограничение (а из-за этого legacy код бы совершенно не пострадал), другой индус-студен решил запретить volatile и для дженериков. Из-за этого мы имеем кривой и косой API. Проехали. Этой гарантии точно также нет и в Java. Нельзя "делегировать" Interlocked, так как volatile и Interlocked -- разные вещи. Ты решил с бараньей упёртостью отстаивать свою безграмотность? Вопрос. Зачем? Я понимаю, шуты причиняют себе вред, ради смеха аудитории, а у тебя какие цели? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 01:10 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Где-то в степивот про это поподробней расскажите пож. если вы про MemoryBarrier то это фактический сброс кеша с последующим объявлением его не действительным- вот и вся синхронизация, или там есть еще какое то шаманство?Нет. Барьер - это не "сброс кэша". Никакого "сброса кэша" не существует. Если забыть про JIT, и рассматривать только железо, то "барьерные инструкции" (напр. с префиксом lock на x86), делают две вещи: 1) При записи, перед тем как ее завершить, ядро ждет, пока store buffer его кэша не флашнется, то есть пока информация о предыдущих записях, которые были сделаны этим ядром, но пока что видны только ему (см. store forwarding), не станет "видна" другим ядрам. "Видна" - это значит, что другие ядра получили запрос на инвалидацию измененных ячеек в своих кэшах. 2) При чтении, перед тем, как ее осуществить, ядро должно обработать свою invalidate queue, то есть применить все запросы на инвалидацию, полученные ранее от других ядер, но еще не обработанные. В этом и есть суть "частичной синхронизации" кэшей разных ядер при выполнении бареров. Кроме того, барьеры запрещают ядрам делать out-of-order execution в их окрестностях. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 01:21 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
cdtyjv1) У вас в приложении генерируются задачи, которые надо выполнять последовательно одну за другой по мере их появления (примерно как это сделано с UI). Как вы этого будете делать? В Java я могу создать отдельный тред пул с ровно одним потоком, и класть в него задачи. Одна строчка кода. В .Net мне надо изобретать свой велосипед с while-циклами, блокирующими колелкциями и прочим дерьмом, которое характерно для тред-пулов. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Но в эпоху тотальной асинхронности это не модно, гораздо моднее так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Но есть подозрение что тебе достаточно будет сделать просто асинхронные методы и асинхронные EventHandler_ы. cdtyjv2) Вы делаете нечто вроде map-reduce фреймворка. Пользователь дает вам задачи, вы их кладете в тред-пул. Каждая задача может сгенерировать другие задачи, которые пойдут в этот же тред-пул, и т.д.. Но кроме пользовательских задач, у вашего приложения еще есть свои системные задачи, которые должны быть гарантированно исполнены и исполнены быстро. Вопрос на засыпку - сможете ли вы использовать ThreadPool в этом случае? Хрен вам, господа! Ведь если юзерские задачи засрут вам пул, то время выполнения вашей системной задачи будет расти пропорционально размеру очереди пользовательских задач. И опять - пищем свои велосипеды. А в Java надо просто создать два разных пула - один для пользователей, один для себя. И все. А в .NET вообще не надо пулы создавать, надо воспользоваться подходящим TaskScheduler, например этим - http://code.msdn.microsoft.com/Samples-for-Parallel-b4b76364/sourcecode?fileId=44488&pathId=1649437731 cdtyjvОчередному индусу в программистском угаре пришла в голову идея сделать ThreadPool статическим, и все - вся идея тут же становится ограниченной и корявой. А надо то было просто конструкторик ThreadPool сделать публичным, что бы разработчики могли создавать свои пулы. Пару строчек кода поленились добавить. Ты снова пытаешься паттерны Java натянуть на .NET. В .NET пул потоков - деталь реализации, не предназначенная для того чтобы там чето самостоятельно шедулить. А то что ты хочешь использовать называется TaskPool (часть TPL) и возможности гораздо шире, чем может предоставить Java. Для особо жестких случаев, когда тасков много и надо нетрививально синхронизировать их между собой есть TPL Dataflow, для твоего первого вопроса надо будет написать так: Код: c# 1. 2. 3. 4. 5. 6.
Что-то похожее есть в RX, но ориентированное на потоки данных . ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 01:55 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
О, Свеном отчаялся самостоятельно справиться со своей задачей и вбросил так, чтобы ему код дали. Почему не создать конкретный топик "Не могу решить вот такую задачу. Помогите.", как это делают остальные? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 02:29 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
Где-то в степи летучесть это фишка записи и чтения данных процессора в контексте его кеша( процессора), если два разных потока крутятся на разных ядрах , работат с переменными оптимизирована через кеш каждого процессора, то есть фактическое изменение переменной задерживается в кеше, а если оно задерживается то второе ядро не может получить реальное значение. volatile дает команду процессору изменить значение переменной минуя ее копию в кеше ( сквозное изменение) и автоматом объявляет кеш не действительным - отсюда и вся гадость со скоростью доступа к кешу ядра ( приходится опять заныривать в оперативку). "летучесть это фишка записи" - Это пять , осталное - ересть. Читать про когерентность кеша. volatile кешем не управляет. Не редкое заблуждение. @cdtyjv " в 64-битной среде, у меня есть ссылка, она занимает 8 байт" В яве не всегда. Смотреть здесь @cdtyjv "2) И зачем он смешал воедино обычныйе треды-воркеры и треды для completion ports?" В CLR два пула. Второй работает с ассинхронным чтением. Строится на основе WinAPI с использованием OVERLAPPED. Много пулов: Подобное решается с использованием scheduler. @hVostt "А конкретно ты можешь «волатильно» прочитать и записать любой тип." @hVostt "Операции с: volatile int a; Точно также не атомарны." Реч конкретно про операцию чтения, а ты обобщяеш. Про общий случай "какой-то операции" речи не было. Или ты утверждаеш что чтение/запись для инт-а не атомарны? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 16:17 |
|
Почему в .Net такие кривые Lock'и?
|
|||
---|---|---|---|
#18+
mikron@hVostt "А конкретно ты можешь «волатильно» прочитать и записать любой тип." @hVostt "Операции с: volatile int a; Точно также не атомарны." Реч конкретно про операцию чтения, а ты обобщяеш. Про общий случай "какой-то операции" речи не было. Или ты утверждаеш что чтение/запись для инт-а не атомарны? Взяли int, что-то с ним сделали, вернули на место. Операция не атомарная. На счёт того, что один читатель, другой писать, тогда ОК, но я об этом уже сказал. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.07.2014, 16:23 |
|
|
start [/forum/topic.php?all=1&fid=20&tid=1402671]: |
0ms |
get settings: |
7ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
31ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
147ms |
get tp. blocked users: |
1ms |
others: | 348ms |
total: | 568ms |
0 / 0 |