- Регистрация
- 16.06.2017
- Сообщения
- 187
- Благодарностей
- 31
- Баллы
- 28
Есть проблема: потоки мешают друг другу работать со списком, привязанном к файлу. Один поток обрабатывает список, вносит туда изменения, но один из параллельных потоков (изредка) делает то же самое, хотя по идее не должен.
Шаблон работает в 5 потоков: они парсят определенную веб-страничку в ожидании определенного "события" на ней. В момент появления этого "события" между пятью потоками происходит драка за то, чтобы первым успеть взять "событие" в работу (а остальные 4 будут ждать другого случая). Если более подробно, выглядит это так:
Когда на страничке появляется "событие", у него есть ID (пишется прямо на страничке). Каждый из 5 потоков мгновенно парсит этот ID, ложит в локальную переменную id1 и тут же ищет совпадение в списке ID_used (привязан к файлу) на предмет того, а не взял ли уже этот ID в работу другой параллельный поток. Если в списке ID_used этого ID еще нет, то он туда записывается, чтобы остальным потокам вернулся ответ "ID уже занят". Был уверен, что такая схема будет работать безотказно, но тесты показали, что иногда в список ID_used один и тот же ID записывается дважды, т.е. сразу оба потока берут его в работу! Хотя поначалу мне казалось это невозможным, ведь, судя по С# коду, список лочится на время проверки, а значит очередь между потоками хоть в доли секунд, но все же должна быть. Я думал, этого времени должно быть достаточно, чтобы между потоками не было конфликта. В общем, прошу подсказки, как реализовать эту схему более грамотно. Схема нынешней реализации представлена ниже:
Шаблон работает в 5 потоков: они парсят определенную веб-страничку в ожидании определенного "события" на ней. В момент появления этого "события" между пятью потоками происходит драка за то, чтобы первым успеть взять "событие" в работу (а остальные 4 будут ждать другого случая). Если более подробно, выглядит это так:
Когда на страничке появляется "событие", у него есть ID (пишется прямо на страничке). Каждый из 5 потоков мгновенно парсит этот ID, ложит в локальную переменную id1 и тут же ищет совпадение в списке ID_used (привязан к файлу) на предмет того, а не взял ли уже этот ID в работу другой параллельный поток. Если в списке ID_used этого ID еще нет, то он туда записывается, чтобы остальным потокам вернулся ответ "ID уже занят". Был уверен, что такая схема будет работать безотказно, но тесты показали, что иногда в список ID_used один и тот же ID записывается дважды, т.е. сразу оба потока берут его в работу! Хотя поначалу мне казалось это невозможным, ведь, судя по С# коду, список лочится на время проверки, а значит очередь между потоками хоть в доли секунд, но все же должна быть. Я думал, этого времени должно быть достаточно, чтобы между потоками не было конфликта. В общем, прошу подсказки, как реализовать эту схему более грамотно. Схема нынешней реализации представлена ниже: