|
Почему в .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 |
|
|
start [/forum/topic.php?fid=20&msg=38705018&tid=1402671]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
43ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 155ms |
0 / 0 |