Выборочная синхронизация потоков.

Тема в разделе "WASM.BEGINNERS", создана пользователем Sercher, 27 июн 2011.

  1. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    Здравствуйте, есть потоки работающие с общим двунаправленным связанным списком, все потоки кроме одно только читают информацию из списка , один поток "основной" добавляет и удаляет записи из списка, сейчас я синхронизирую чтение/запись через мутекс который захватывается всеми читающими потоками и также основным потоком при необходимости удаления удалении записи. По идеи все читающие потоки должны синхронизироваться только с "основным" потоком но не между собой, так как ошибка доступа возможна лишь при удалении записи и одновременном чтении из нее. Вот и возник вопрос как синхронизировать доступ к области памяти только между "Основным" потоком и всеми читающими, т.е. производить блокировку читающих потоков только при необходимости удаления.

    Сейчас делаю так:

    Все читающие потоки:
    В начале чтения ждем захвата общего мутекса
    читаем
    освобождаем мутекс

    "Основной поток"
    чтение и добавление производим без захват мутекса
    при удалении захватываем мутекс.
    удаляем
    освобождаем мутеск.

    Как видно при работе по такой схеме все потоки чтения синхронизируются не только с основным потоком но и между собой, из-за чего тратиться много времени на ожидание перед чтением.
     
  2. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    Читающий тред:
    1. Инкремент счётчика потоков, обращающихся к ресурсу.
    2. Проверяем переменную W. Если TRUE, то ждём на эвенте W.
    3. Читаем ресурс.
    4. Декремент счётчика потоков.
    5. Если счётчик потоков = 0, то сигнализируем евент R.

    Пишущий тред:
    1. Устанавливаем переменную W в TRUE.
    2. Проверяем счётчик потоков, если отличен от нуля, то ждём на эвенте R.
    3. Пишем ресурс.
    4. Устанавливаем переменную W в FALSE и сигнализируем эвент W.

    Пара эвентов - это обьект EventPair.
     
  3. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Смотрите технику RCU (Read-Copy-Update) + атомарность операций. Проблемы возможны, как вы правильно отметили, только при удалении элемента -- здесь используйте Mutex или лучше его самописный аналог, т.к. Mutex'ы достаточно медленны.
     
  4. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    Техника понятна правда инкремент счетчика тоже придется синхронизировать (через префикс lock возможно?(lock inc))?
    Спасибо.
    П.С. Возможна ошибка?: если два треда Читающий и Пишущий пойдут одновременно с п1. то оба зависнут в ожидании события W/R навсегда.
     
  5. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    Да я сам подумываю сменить их на критические секции, там где еще мутексы остались.(правда нашлись подводные камни, если поток не освободит крит. секцию до закрытия (ошибка в работе птока) то все остальные потоки ждущие ее зависнут намертво, при юзании мутекса они отвиснут после закрытия потока не отпустившего мутекс)
     
  6. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Ну так отслеживайте когда потоки завершаются, это ж ваш код надеюсь ;)
     
  7. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Sercher
    Если совместимость с версиями ниже Vista не планируется, можно использовать SRWLock - облегчённый вариант критической секции, специально разработан для подобных случаев.
     
  8. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    А вы с переменными условиями не сталкивались?
     
  9. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    в основном XP ,2000, (вист и 7 меньше половины)
     
  10. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    Не используйте ExitThread(), используйте try-блоки и будет вам счастье :)
     
  11. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    А по топику есть у кого какие идеи?
     
  12. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    klzlk
    a) Приходит читающий поток, выполняет свой п.1.
    Переключение потока.
    b) Приходит пишущий поток, выполняет свои п.1, п.2 и виснет на событии R, т.к. счётчик потоков превышает нуль.
    Возобновление читающего потока.
    с) Читающий поток видит, что W установлена и виснет на событии W.

    His majesty, deadlock.
     
  13. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    l_inc
    Ну да, я забыл местами поменять первые пункты. Проверка и изменение атомарны - lock cmpxchg. Аналогично как в критических секциях например.
     
  14. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    klzlk
    Ну и какой тогда правильный вариант получится, если поменять? Хочу посмотреть, что Вы без матчасти придумаете. А то не стоило ведь бросать универ. :) Reader-Writer cooperation, знаете ли, в программу первых двух лет входит (у нас на теории ОС на третьем семестре было).
    У Вас в алгоритмах нету проверки и измения одной и той же переменной в пределах одного пункта. Так что lock cmpxchg применить не к чему.
     
  15. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    l_inc
    Это псевдокод. Можно стопяцот причин найти, почему он не будет работать. Псевдокод это максимально краткое описание алгоритма.

    Вам студентик наверно обьяснили что такое Event Pair..
     
  16. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    klzlk
    Ага. К тому же неправильный. Первая причина есть. А за правильным псевдокодом предлагаю обратиться к Таненбауму (Операционные системы. Разработка и реализация).
    Event pair студентику не нужно, т.к. не является базовым примитивом синхронизации. А специфические объекты ядра Windows к базовому образованию не относятся.
     
  17. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    l_inc
    Говорю же, поменяйте два первых пункта местами.

    Без оси ваше образование никому нафиг не нужно. Дифференцируйте дальше.)
     
  18. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    klzlk
    Спрашиваю же, что получится. Какие первые два менять? У читающего? У пишушего? У обоих?
    В любом случае будет нарушение условий взаимоисключающего доступа.
     
  19. Sercher

    Sercher New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    59
    Я уже давно об этом написал см. выше в п.с.
    Сейчас для осей выше ХР юзаю srwlock(прекрасная штука!), для остальных версий ОС,пока ищу ...
     
  20. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Sercher
    Да-да. Пару часов после моего поста я заметил. :) Но, т.к. klzlk заметил свою ошибку только после моего поста, пост стоил повторения. :)
    Что искать? Я ж уже предложил глянуть у Таненбаума. Предложение предназначалось в основном Вам.