powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Почему в .Net такие кривые Lock'и?
17 сообщений из 67, страница 3 из 3
Почему в .Net такие кривые Lock'и?
    #38705520
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvИзопропилпропущено...

да, это так.Нет, это не так. volatile и сериализует доступ к конкретной переменной (напр. к long на 32-битной платформе), и является примитивом синхронизации благодаря окружающим его барьерам памяти.

Покажи код где этот "примитив синхронизации" таки синхронизирует доступ двух потоков к одним и тем же данным.

Сериализация доступа к переменным не дает вообще ничего.
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705521
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvДа, так и есть. Просто криворукие разработчики .Net решили не давать гарантии атомарности long/double, из-за чего и возник весь сыр-бор с невозможностью объявить их volatile, а оттуда же выросли проблемы с дженериками, которые так же нельзя объявить волатилями. Одно тупое решение какого-то неквалифицированного индуса, и API .Net превратился в гомно.

Операции с:

volatile int a;

Точно также не атомарны. Ради всех цвятых, открой букварь и почитай. Зачем демонстрировать безграмотность? Открыл, почитал, всё понял, закрыл, поумнел = больше не говоришь глупостей.
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705522
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvЧто я не понимаю?
То что волатильность доступа не дает ничего с точки зрения синхронизации потоков.
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705523
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvиспользуют volatile / Interlocked для попытки быстрого захвата ресурса

нельзя
можно

использовать для захвата ресурсов.
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705525
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
myVolatileVar++;


The previous statement could also be written as follows:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int temp = 0;
synchronize( myVolatileVar ) {
  temp = myVolatileVar;
}

temp++;

synchronize( myVolatileVar ) {
  myVolatileVar = temp;
}


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 .
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705526
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvУгу, не используется. Например, вот здесь это не используется http://referencesource.microsoft.com/#mscorlib/system/threading/SpinLock.cs

Синхронизация обеспечивается не волатильностью, а interlocked - атомарными операциями. И это не одно и тоже.
Волатильность нужна чтобы разные процессоры не считали что у одно и того же лока в один и тот же момент времени разные владельцы.

Причем если убрать "владельца", то можно синхронизацию запилить и без volative (получится классический lock-free).
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705527
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705528
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ладно, с кривотой 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 сделать публичным, что бы разработчики могли создавать свои пулы. Пару строчек кода поленились добавить.
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705530
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv,

А расскажи честно, зачем тебе volatile вообще понадобился? Пример кода приведи.
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705531
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv,
автор Он их не отличает я Вы что то мне приписываете, я где то сказал что это особая инструкция?
авторкоторые гарантируют частичную синхронизацию состояний кешей между собой
вот про это поподробней расскажите пож.
если вы про MemoryBarrier то это фактический сброс кеша с последующим объявлением его не действительным- вот и вся синхронизация, или там есть еще какое то шаманство?
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705545
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvЛадно, с кривотой volatile я разобрался. Причина: какой-то индус-студент, пришедший в Microsoft набраться опыта, решил не давать гарантии атомарности чтений/записей типам long/double, хотя это сделать эелментарно (хотя бы просто делеировать в Interlocked). Потом через какое-то время появились дженерики, за которыми могли стоять все те же long и double. Но вместо того, что бы снять это ограничение (а из-за этого legacy код бы совершенно не пострадал), другой индус-студен решил запретить volatile и для дженериков. Из-за этого мы имеем кривой и косой API. Проехали.

Этой гарантии точно также нет и в Java.
Нельзя "делегировать" Interlocked, так как volatile и Interlocked -- разные вещи.

Ты решил с бараньей упёртостью отстаивать свою безграмотность?

Вопрос. Зачем? Я понимаю, шуты причиняют себе вред, ради смеха аудитории, а у тебя какие цели?
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705547
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степивот про это поподробней расскажите пож.
если вы про MemoryBarrier то это фактический сброс кеша с последующим объявлением его не действительным- вот и вся синхронизация, или там есть еще какое то шаманство?Нет. Барьер - это не "сброс кэша". Никакого "сброса кэша" не существует. Если забыть про JIT, и рассматривать только железо, то "барьерные инструкции" (напр. с префиксом lock на x86), делают две вещи:
1) При записи, перед тем как ее завершить, ядро ждет, пока store buffer его кэша не флашнется, то есть пока информация о предыдущих записях, которые были сделаны этим ядром, но пока что видны только ему (см. store forwarding), не станет "видна" другим ядрам. "Видна" - это значит, что другие ядра получили запрос на инвалидацию измененных ячеек в своих кэшах.
2) При чтении, перед тем, как ее осуществить, ядро должно обработать свою invalidate queue, то есть применить все запросы на инвалидацию, полученные ранее от других ядер, но еще не обработанные.
В этом и есть суть "частичной синхронизации" кэшей разных ядер при выполнении бареров.

Кроме того, барьеры запрещают ядрам делать out-of-order execution в их окрестностях.
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705553
gandjustas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv1) У вас в приложении генерируются задачи, которые надо выполнять последовательно одну за другой по мере их появления (примерно как это сделано с UI). Как вы этого будете делать? В Java я могу создать отдельный тред пул с ровно одним потоком, и класть в него задачи. Одна строчка кода. В .Net мне надо изобретать свой велосипед с while-циклами, блокирующими колелкциями и прочим дерьмом, которое характерно для тред-пулов.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var queue = new BlockingCollection<Action>();
Task.Factory.StartNew(() =>
{
    foreach (var action in queue.GetConsumingEnumerable())
    {
        action();
    }
}, TaskCreationOptions.LongRunning);

queue.Add(() => Console.WriteLine("Hello task"));
queue.CompleteAdding();



Но в эпоху тотальной асинхронности это не модно, гораздо моднее так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var queue = new BlockingCollection<Task>();
Task.Factory.StartNew(async () =>
{
    foreach (var task in queue.GetConsumingEnumerable())
    {
        await task.ConfigureAwait(false);
    }
});
            
queue.Add(Console.Out.WriteAsync("Hello task"));
queue.CompleteAdding();



Но есть подозрение что тебе достаточно будет сделать просто асинхронные методы и асинхронные 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.
      var workerBlock = new ActionBlock<Action>(action => action(),
         new ExecutionDataflowBlockOptions
         {
            MaxDegreeOfParallelism = 1
         });
workerBlock.Post(() =>Console.WriteLine("Hello task"));



Что-то похожее есть в RX, но ориентированное на потоки данных .
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38705562
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О, Свеном отчаялся самостоятельно справиться со своей задачей и вбросил так, чтобы ему код дали.

Почему не создать конкретный топик "Не могу решить вот такую задачу. Помогите.", как это делают остальные?
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38706165
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степи летучесть это фишка записи и чтения данных процессора в контексте его кеша( процессора), если два разных потока
крутятся на разных ядрах , работат с переменными оптимизирована через кеш каждого процессора, то есть фактическое изменение
переменной задерживается в кеше, а если оно задерживается то второе ядро не может получить реальное значение.
volatile дает команду процессору изменить значение переменной минуя ее копию в кеше ( сквозное изменение) и автоматом объявляет кеш не действительным - отсюда и вся гадость со скоростью доступа к кешу ядра ( приходится опять заныривать в оперативку).

"летучесть это фишка записи" - Это пять , осталное - ересть.
Читать про когерентность кеша.
volatile кешем не управляет. Не редкое заблуждение.

@cdtyjv " в 64-битной среде, у меня есть ссылка, она занимает 8 байт" В яве не всегда. Смотреть здесь
@cdtyjv "2) И зачем он смешал воедино обычныйе треды-воркеры и треды для completion ports?"
В CLR два пула. Второй работает с ассинхронным чтением. Строится на основе WinAPI с использованием OVERLAPPED.
Много пулов: Подобное решается с использованием scheduler.

@hVostt "А конкретно ты можешь «волатильно» прочитать и записать любой тип."
@hVostt "Операции с: volatile int a; Точно также не атомарны."
Реч конкретно про операцию чтения, а ты обобщяеш. Про общий случай "какой-то операции" речи не было.
Или ты утверждаеш что чтение/запись для инт-а не атомарны?
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38706171
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikron@hVostt "А конкретно ты можешь «волатильно» прочитать и записать любой тип."
@hVostt "Операции с: volatile int a; Точно также не атомарны."
Реч конкретно про операцию чтения, а ты обобщяеш. Про общий случай "какой-то операции" речи не было.
Или ты утверждаеш что чтение/запись для инт-а не атомарны?

Взяли int, что-то с ним сделали, вернули на место. Операция не атомарная. На счёт того, что один читатель, другой писать, тогда ОК, но я об этом уже сказал.
...
Рейтинг: 0 / 0
Почему в .Net такие кривые Lock'и?
    #38706173
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronvolatile кешем не управляет

и не должын. так почему кто-то решил, что это должно быть так?
может кто-то сильно грамотный так сказал.
...
Рейтинг: 0 / 0
17 сообщений из 67, страница 3 из 3
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Почему в .Net такие кривые Lock'и?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]