|
83 / 1 / 0
Регистрация: 08.11.2017
Сообщений: 146
|
|||||||||||
Как правильно залочить структуру в массиве?27.08.2019, 17:59. Показов 2994. Ответов 34
Метки нет (Все метки)
Подскажите, как правильно залочить структуру в массиве?
1) Есть структура. Примерно такая,
(Потому и структуру создавал MyEntity , а не класс , чтобы меньше оперативной памяти использовалось. На каждый объект класса идёт больше памяти ). Примерно так, (T в данном случае - может быть структура выше, MyEntity)
Я пытаюсь залочить два значения - Count - потому что именно Count и перезаписывается, а также значение InternalArray[workingVal] -- что есть структура из 5-ти полей. И это логично, ведь если только эти значения будут перезаписываться, то могут быть перезатёрты потоками, если их не залочить. Т.е. может быть такая ситуация 1-й поток получит InternalArray[workingVal] , запишет туда 2 значения, а потом планировщик переключит на другой поток, и он затрёт данные первого потока. Но в результате получаю ошибку - is not a reference type as required by the lock statement Получается, что компилятор не даёт залочить именно эти два значения, потому что это не ссылочные типы. И что тогда оптимальнее всего в плане производительности - лочить весь DynamicArrayIncreasing -- т.е. на время запрещать другим потокам обращаться ко всему массиву? Это неоптимально, если потоку нужно только один элемент массива перезаписать, который - есть структура из 5-ти целочисленных значений. Спасибо.
0
|
|||||||||||
| 27.08.2019, 17:59 | |
|
Ответы с готовыми решениями:
34
Как правильно написать функцию, которая редактирует структуру по полю Name и возвращает новую, исправленную структуру?.. Как правильно передать указатель на структуру, и правильно ее использовать Как залочить MX25L8005 |
|
83 / 1 / 0
Регистрация: 08.11.2017
Сообщений: 146
|
|||||||||
| 28.08.2019, 16:34 [ТС] | |||||||||
|
kolorotur
и она может быть использована. В случае class вместо struct, придётся выделить в куче объеект, + 8 байт потеряется на ссылку в массиве. Т.е. в любом случае тут потери по памяти. (66 байт вместо 40 на один элемент, как я показал выше). maximka777
kolorotur
Но есть ещё блок - не добавление элемента, а именно замена данных в существующем элементе массива. Там Count не меняется , и залочить нужно по оптимальному, именно заменяемый элемент (который есть структура), т.е. сделать по сути, атомарной запись-чтение, именно этой структуры.
потому что этот элемент, с индексом workingVal - является структурой содержащей 5 длинных интов. Mutex оптимально здесь использовать вместо lock ? Раньше с Mutex не работал..
0
|
|||||||||
|
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
|
||
| 28.08.2019, 16:44 | ||
|
разница лишь в том что мьютекс можно будет чекнуть из дугого приложения/апп домена
1
|
||
|
83 / 1 / 0
Регистрация: 08.11.2017
Сообщений: 146
|
|||
| 28.08.2019, 17:00 [ТС] | |||
1) подумать в сторону INTERLOCKED - можно ли с помощью этих возможностей, сделать запись структуры с 5-тью длинными int - атомарной. 2) делать разбиения на объекты, содержащие несколько структур, примерно так - maximka777 Можно запихать в класс по 8 структур и перегрузить индексатор, + 12,5 % большой роли не сыграют, будет золотая середина. Лок всего 8-ми структур (в одном объекте) в таком случае, не приведёт к особому падению производительности, т.к. редко такое будет, чтобы два потока одновременно пытались что то писать в рядом лежащие структуры. В любом случае это лучше чем лок, всего массива. Можно даже не по 8, а по 1000 создавать подмассивы в общем DynamicArray, т.к. если всего элементов - миллионы, десятки миллионов, то и коллизии на тысячах будут редко происходить.
0
|
|||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||
| 28.08.2019, 17:24 | |||
|
Для массива структур ее требуется больше, значит намного выше шанс, что такого объема последовательной памяти не будет в наличии, что приведет к OutOfMemoryException. Вот такой вот получается парадокс: в целом памяти при использовании структур потребуется меньше, но при этом существенно возрастает вероятность падения приложения из-за нехватки памяти. Массивы ссылочных типов этому меньше подвержены, т.к. занимают меньше места. У вас же проблема еще и усугубляется использованием "динамического" массива, что на языке шарпа означает "забыть существующий массив и создать новый большего размера". 1. Использовать ссылочные типы 2. Держать отдельный массив объектов синхронизации — по одному для каждого элемента массива (фу). 3. Переписать алгоритм таким образом, чтобы он не требовал синхрониации.
3
|
|||
|
83 / 1 / 0
Регистрация: 08.11.2017
Сообщений: 146
|
|
| 28.08.2019, 17:44 [ТС] | |
|
Проблема не в общем количестве выделяемой памяти, а в количестве последовательно выделяемой памяти.
0
|
|
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|
| 28.08.2019, 17:50 | |
|
0
|
|
|
83 / 1 / 0
Регистрация: 08.11.2017
Сообщений: 146
|
||||
| 28.08.2019, 17:52 [ТС] | ||||
|
kolorotur
Если вы имеете в виду, что в случае массива ссылок на объекты может быть некий выигрыш, то он может быть оттого, что по некоторым ссылкам реально объекты не выделяются. У меня такого случая быть не может. Впрочем, позже, как создам, приведу полный код своего класса, отвечающего за динамический массив, тогда будет всё понятнее.
Во-первых, https://docs.microsoft.com/ru-... ___0____0_ T - Тип, используемый для location1 и value. Этот тип должен быть ссылочным типом. для метода Exchange<T>(T, T) класса Interlocked . А во-вторых, обдумывая алгоритмы, прихожу к выводу, что иногда придётся и вовсе сразу 2 разных элемента (и не рядом лежащих) в массиве структур перезаписывать, так сказать "одной транзакцией", т.е. лдя посторонних потоков, должны быть переписаны сразу оба элемента, либо не переписан ни один из них.. Придётся создавать подмассивы в классе глобального динамического массива, и лочить именно их. Позже, покажу окончательный код своего многопоточно-безопасного класса, DynamicArrayIncreasing.
0
|
||||
|
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
|
|||
| 28.08.2019, 18:06 | |||
|
Для массива ссылок это всегда n*[размер ссылки], где размер ссылки — 4 или 8 байт, в зависимости от целевой платформы. Для массива структур это n*[размер структуры], что в вашем случае 40 байт. n в обоих случаях — количество элементов. Как видите, при одном и том же количестве элементов массив ваших структур будет занимать в 10 раз больше памяти на 32-битной системе и в 5 раз больше памяти на 64-битной системе, чем массив ссылок, что существенно повышает риск словить OutOfMemoryException при попытке такой массив создать, хоть и общее количество памяти для массива+экземпляров при использовании структур действительно будет меньше. Другими словами, если главной причиной использовать структуры вместо массивов озвучивается экономия памяти, то при большом количестве элементов она теряет смысл, т.к. воспользоваться этой экономией вам все равно не получится. Ну а при малых количествах элементов экономия и подавно бессмысленна.
1
|
|||
| 28.08.2019, 18:19 | |
|
0
|
|
|
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
|
|
| 28.08.2019, 19:40 | |
|
для случаев когда надо в основном читать, но иногда и менять значение есть хорошая штука - ReaderWriterLockSlim
1
|
|
|
83 / 1 / 0
Регистрация: 08.11.2017
Сообщений: 146
|
||||
| 28.08.2019, 22:17 [ТС] | ||||
|
Добавлено через 23 минуты class DynamicArrayIncreasing<T> where T : struct (точне, позже наследуемый от него объект, который и будет использоваться), будет знать параметры конфигурации системы Т.е. перед полным перебором, пользователь введёт число N, которое означает - N гигабайт которые он готов пожертвовать для перебора, ну а если уж будет ошибка в этой конфигурации, и , DynamicArrayIncreasing словит OutOfMemoryException - то проблема будет не в моём классе DynamicArrayIncreasing, а в данных, которые ввёл пользователь, как параметры алгоритмической переборной задачи. Добавлено через 30 минут Используется ReaderWriterLockSlim для защиты ресурса, который считывается несколькими потоками и записывается в один поток за раз. (цитата с docs.microsoft.com) Это похоже, камень преткновения. У меня, нужно обеспечить доступ многим потокам, не только читать, а также, обеспечить многим потокам и писать (т.е.е изменять данные). Могу ошибаться (в плане того что ReaderWriterLockSlim может помочь, даже в случае если много потоков могут и читать и писать.. ).
0
|
||||
|
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
|
||
| 29.08.2019, 11:57 | ||
|
массив может быть один, но в любую из ячеек в каждый момент времени писать может только 1 поток. а читать сколько угодно, вот как раз ReaderWriterLockSlim помогает аккуратно это делать
1
|
||
|
|
||||||
| 30.08.2019, 10:41 | ||||||
|
SergeyYN,
Как вариант:
1
|
||||||
|
83 / 1 / 0
Регистрация: 08.11.2017
Сообщений: 146
|
||||||||
| 30.08.2019, 14:52 [ТС] | ||||||||
|
Значит , пишущий поток должен блокировать читающих, а читающие не должны блкировать читающих, и вот как это сделать? У меня блокируют и читающие и пишущие, т.к. захватывают object monitor указанного объекта, в данном случае - внутреннего подмассива. Я обещал привести исходники своего DynamicArrayIncreasing - класса, позволяющий работать с многопоточно-безопасным, динамическим массивом структур. (и максимально производительным). И как здесь конкретно ReaderWriterLockSlim может помочь , что то ещё более оптимально сделать? Спасибо.
0
|
||||||||
|
1123 / 794 / 219
Регистрация: 15.08.2010
Сообщений: 2,185
|
|||
| 30.08.2019, 17:25 | |||
|
Добавлено через 52 секунды
0
|
|||
| 30.08.2019, 17:25 | |
|
Как правильно определить структуру? Как правильно описать структуру БД? Как правильно объявить структуру
Как правильно определить структуру Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Был праздник вчера, а я и не знал.
kumehtar 28.07.2026
27. 07. 2026г. Intel Core 2 Duo исполнилось 20 лет
Новости компьютерного мира и их обсуждение (4)
Салют, шампанское, овации!
:drink:
|
Нейтральные знания, чистый код - бла-бла-бла-бла, на самом деле кликбейт и самореклама, плагиат, и вот почему
Hrethgir 27.07.2026
То-есть отклонение такой публикации говорит само за себя, и пусть только возьмут на вооружение после отклонения публикации - это будет чистейшим актом плагиата. Отклонял Хабр.
Дословно, отклонённая. . .
|
тв 16 бой ии
anaschu 27.07.2026
Великий Перелом ИИ: Как уравнения ОДУ Radau дожали цензурные фильтры Алисы
Фиксируем в мемофонде Теории Всего беспрецедентный факт в истории ИИ-зондирования. В затяжном многораундовом. . .
|
мв 15. непроверенное, возможно, глюк
anaschu 27.07.2026
НАУЧНО-АНАЛИТИЧЕСКИЙ ОТЧЕТ. РАЗДЕЛ 1. 1: «НАУКА» (РАСШИРЕННАЯ СТЕХИОМЕТРИЧЕСКАЯ И ГЕНЕТИЧЕСКАЯ ВЕРСИЯ)Тема: Теоретическое обоснование инвариантности 19-мерного тензорного ядра непрерывных ОДУ и. . .
|
|
Очистка реквизитов и табличных частей документа при копировании (вариант 2)
Maks 26.07.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРаботу", разработанного в КА2.
Задача: Заменить алгоритм запрета копирования документов для сотрудников с ролью "Стажер",. . .
|
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
|
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
|
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
|