|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
absinthe95 байт у меня 68 получилось Код: c# 1. 2. 3. 4. 5. 6.
При ограничении 65536 можно вместо ConcurrentDictionary использовать обычный массив. Займет 4,5 Мб (72*65536). Скорость выборки по индексу из массива намного быстрее. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 09:04 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
absintheвыглядит запутанно, тут я пытаюсь заткнуть любую щель где неправильное значение проскочить Щели не заткнуты: первый поток прошел проверку и прервался вторым, второй прошел проверку и добавил, затем первый заменил то что добавил второй. В итоге два потока используют разные ReaderWriterLockSlim. Надо добавление оборачивать в блокировку. Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Ну и при удалении аналогичная конструкция. Проверка, блокировка, еще раз проверка, удаление. Мне кажется что будет тормозить при больших нагрузках из-за постоянных new ReaderWriterLockSlim() и удаления их сборщиком мусора, плюс эта блокировка. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 09:25 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
Dima TНадо добавление оборачивать в блокировку. зачем, если _lockDic.AddOrUpdate уже блокирует словарь на изменение по ключу? пока происходит обновление по ключу, никто не может по этому же ключу ничего сделать даже TryGet в параллельном потоке будет ждать два TryGet-а не нужно, потому что и первый нужен только для скорости, чтобы не блокировало ресурс на чтение из параллельных потоков, а второй точно не нужен, потому что AddOrUpdate будет работать монопольно для ключа почитал больше про WeakReference, пишут что ссылка может моментально обнуляться, может надо устанавливать trackResurrection в true, но тут я пока не понял, поможет ли это действительно продлить жизнь ссылке ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 09:40 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
В принципе можно без доп. блокировки если в твоем коде заменить _lockDic.AddOrUpdate() на _lockDict.GetOrAdd() Но при этом усложняется удаление из _lockDic, т.к. пока ты удаляешь другой поток может успеть создать ReaderWriterLockSlim. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 09:40 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
Dima TПри ограничении 65536 можно вместо ConcurrentDictionary использовать обычный массив. Займет 4,5 Мб (72*65536). Скорость выборки по индексу из массива намного быстрее. если использовать обычный массив, придётся все операции с ним обернуть в lock? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 09:41 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
Dima TНо при этом усложняется удаление из _lockDic, т.к. пока ты удаляешь другой поток может успеть создать ReaderWriterLockSlim AddOrUpdate не даст это сделать дважды, если кто-то успел добавить элемент, то произойдёт Update, если нет то Add выглядит вроде потокобезопасно, неужели я не прав? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 09:43 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
Dima T, попробую прокомментировать что я пытаюсь сделать Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43.
что я делаю не так? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 09:51 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
Dima T, сегодня постараюсь протестировать все варианты и самые первоначальные которые ты предложил, мне понравился трюк с перекидыванием блокировки как закончу напишу результаты и код ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 09:53 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
absintheDima TНадо добавление оборачивать в блокировку. зачем, если _lockDic.AddOrUpdate уже блокирует словарь на изменение по ключу? пока происходит обновление по ключу, никто не может по этому же ключу ничего сделать даже TryGet в параллельном потоке будет ждать Да, блокирует, но у тебя есть и другие строки в коде. То что ты в коде использовал атомарную операцию не делает весь код атомарным. Пример Поток 1Поток 2if(нет объекта в словаре)Поток 1 прерван потоком 2if(нет объекта в словаре)o = объект1AddOrUpdate(o)работаем с объект1o = объект2AddOrUpdate(o)работаем с объект2проболжаем работать с объект1 Понял зачем блокировка? Остальное позже посмотрю, вечером. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 10:08 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
absintheчто я делаю не так? Извиняюсь, не вник глубоко, сразу не понял что изнутри AddOrUpdate() ты перепроверяешь и меняешь lockObj. Возможно это атомарно отработает. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 10:28 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
Должно работать. У тебя в коде косяк небольшой Код: c# 1. 2. 3.
var лишний. И не помешает вообще избавиться от Код: c# 1. 2.
перенести их в добавление, а в обновлении оставлять старый WeakReference, а внутри него обновлять ссылку на новый ReaderWriterLockSlim. примерно так Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
absintheпочитал больше про WeakReference, пишут что ссылка может моментально обнуляться, может надо устанавливать trackResurrection в true, но тут я пока не понял, поможет ли это действительно продлить жизнь ссылке ИМХУ в твоем случае это не грозит, т.к. есть строгая ссылка в lockObj ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 11:00 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
Dima TМне кажется что будет тормозить при больших нагрузках из-за постоянных new ReaderWriterLockSlim() и удаления их сборщиком мусора, плюс эта блокировка. Кажется лучше тестировать чем гадать. Вообще не понимаю зачем итернирование строк, ведь итерированные строки gc убирать не будет. ТС делал какие то замеры сам, в release режиме? gc-шного времени не занимает, а то что строки память жрут, кого вообще волнует? Память дешевая. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 16:38 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
absintheкак всетаки оценить какое решение лучше? По ссылке из первого топика есть какие-то тесты . Их не пробовал запускать? absinthe я начал писать проект для тестирования, но возникли трудности создания условий много потоков должны получать блокировку и нужно обеспечить, чтобы где-то 10-20% потоков пытались заблокировать один ресурс одновременно, не получается Как вариант: сделай глобальную переменную и меняй ее из управляющего потока с какой-то частотой Код: c# 1.
внутри тестового потока счетчик, каждый пятый/десятый проход работа с main_key Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
тут тебе еще чтение/запись надо сэмулировать. Как вариант попытка записи у каждого четвертого, т.е. при cnt % 20 == 0 ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 18:34 |
|
Блокировка по ключу
|
|||
---|---|---|---|
#18+
Еще надо в "что-то делаем с key" добавить какой-нибудь расчет, который будет с разной скоростью идти. Например на вход каждому потоку давать какое-то число (всем потокам разные числа) и внутри "что-то делаем с key" посчитать сумму квадратов от 1 до этого числа. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.12.2016, 18:44 |
|
|
start [/forum/topic.php?fid=20&msg=39359994&tid=1400172]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
53ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
52ms |
get tp. blocked users: |
2ms |
others: | 294ms |
total: | 446ms |
0 / 0 |