Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
Многопоточность: блокировка чтения при записи.
#1
Допустим есть список в котором что то храним.
Код:
private static OrderedDictionary<int, string> testMem = new OrderedDictionary<int, string>();

        public static void [color=Red]addIntString[/color](int testInt, string testString)
        {
            testMem.Add(testInt, testString);
        }
        public static string [color=Lime]getStringByInt[/color](int testInt)
        {
            string testString;
            testMem.TryGetValue(testInt, out testString);
            return testString;
        }

К данному списку обращается множество потоков.
нужно заблокировать чтение(выполнение зеленого) если другой поток выполняет запись(выполняется красный метод) и восстановить работу зеленого как только красный закончит работу.
Причем чтение может выполнятся "одновременно" несколькими потоками если только не выполняется запись... по этому lock(object) ко всем методам не подходит. Чет не могу сообразить как это красиво реализовать...

Добавлено через 7 минут
Блин вот тупил часа 2, создал тему и тут же вспомнил про ManualResetEvent и все встало на свои места. Тема закрыта. А вообще самое лучше решение - ReaderWriterLock
Ответ
#2
krisadr;417028 Написал:Причем чтение может выполнятся "одновременно" несколькими потоками если только не выполняется запись... по этому lock(object) ко всем методам не подходит.

А Почему бы и не блокировать на время чтения? Это же сортированный словарь. Чтение выполняется практически мгновенно. Врятли тут будет затык по скорости.
Ответ
#3
очень часто выполняется чтение и очень редко запись, объемы большие
Ответ
#4
на каждый словарь повесишь замок? не гони, на прямые операции add\remove слишком жирно будет, вот как начнешь итерировать - тогда подумай.
и с объемами подумай, ибо шарп не может в большие словари.
Ответ
#5
Если вам нужна потокобезопасность - используйте ConcurrentDictionary

https://msdn.microsoft.com/en-us/library...2147217396
Ответ
#6
ANZO Написал:Если вам нужна потокобезопасность - используйте ConcurrentDictionary

https://msdn.microsoft.com/en-us/library...2147217396
да я в курсе про такие словари\коллекции по принципу copyOnRead - теряем скорость

реализовал так (нужно параллельное чтение, а запись может и подождать, пока все потоки не прочитаются)
ReadWriteLockerSlim и стандартный не использовал ибо они ограничивают read
Код:
public sealed class ReadWriteLockerPro
    {
        #region private
        #region vars
        private ManualResetEvent writeLock = new ManualResetEvent(true);
        private ManualResetEvent readLock = new ManualResetEvent(true);
        private volatile int readers = 0;
        #endregion
        #region methods
        #endregion
        #endregion

        #region public
        #region methods
        public void enterWriteLock()
        {
            readLock.WaitOne();
            writeLock.Reset();
        }
        public void exitWriteLock()
        {
            writeLock.Set();
        }
        public void enterReadLock()
        {
            writeLock.WaitOne();
            readLock.Reset();
            Interlocked.Increment(ref readers);
        }
        public void exitReadLock()
        {
            Interlocked.Decrement(ref readers);
            if (readers == 0)
                readLock.Set();
        }
        #endregion
        #region get/set
        #endregion
        #endregion
    }

По моему в полне годно

Добавлено через 9 минут
KID Написал:на каждый словарь повесишь замок? не гони, на прямые операции add\remove слишком жирно будет, вот как начнешь итерировать - тогда подумай.
и с объемами подумай, ибо шарп не может в большие словари.

словари берутся из этой либы (PowerCollections.dll) - ссылку на ресурс потерял, но разраб утверждает кто коллекции спецом оптимизированы под большие обьемы
Ответ
#7
krisadr, есть ситуации, когда в реальных условиях всякое годно превращается в говно. ну а либу, релизнутую в 2007, я бы очканул использовать. в любом случае метод тыка и ошибок самый полезный!
Ответ


Перейти к форуму:


Пользователи, просматривающие эту тему: 1 Гость(ей)