Многопоточность и архитектура. Объясните простые вещи.
От: Аноним  
Дата: 17.06.11 05:20
Оценка:
Здравствуйте,

Нужно проверить все файлы на диске. Создаем несколько типов задач для этого: обход директории, чтение файла, проверка.
Самое длительное — обход директории, выполняется в одном потоке, собирает файлы. Далее читаем и проверяем полученные файлы в несколько потоков.
Так вот объясните самым понятным языком, как реализовать управление такими задачами.

Непонятно вот что:
извне может поступить сигнал — паузка, остановка, продолжение.

Как это реализовать просто и расширяемо? Как работает SetEvent? Мы его создаем CreateEvent, и ждем WaitForSingleObject. Когда нужно выполнить задачу в пуле,
делаем SetEvent, что происходит в этот момент??
Почему во всех реализациях пулов потоков, нет простых операций: Pause, Resume, Stop, OnTaskStart, OnTaskEnd?

Мне нужно максимально простое решение с точки зрения архитектуры. Чтобы допустим, при добавлении задачи: "загрузка сигнатур", это не затрагивало задачу "проверка файла".

Спасибо.
Re: Многопоточность и архитектура. Объясните простые вещи.
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 17.06.11 06:08
Оценка: 2 (1)
А>Почему во всех реализациях пулов потоков, нет простых операций: Pause, Resume, Stop, OnTaskStart, OnTaskEnd?

Потому что пул потоков — это низкоуровнивый примитив. Не такой низкоуровнивый как "поток" или "объект синхронизации типа event", но примитив. Сам по себе он, увы, ничего не может. То что вы хотите — это уже "движок программы". Который пишется с использованием примитивов. Можно с помощью пула потоков, можно с помощью просто потоков и примитивов синхронизации. А уж у самого движка есть и Pause, и Resume, и OnTaskStart, и аже onTaskEnd. Как раз недавно такой писал . Написать такой движок не очень сложно, в зависимости от используемых библиотек это 50-500 строк. Я на Qt где-то в 100 уложился.

А>Как это реализовать просто и расширяемо? Как работает SetEvent? Мы его создаем CreateEvent, и ждем WaitForSingleObject. Когда нужно выполнить задачу в пуле,

А>делаем SetEvent, что происходит в этот момент??

Ну это как бы надо почитать документацию по используемому вами языку и фреймворку. Вы же не надеетесь, что вам тут зачитают лекцию по языку программирования, его библиотекам и по мультипоточному программированию? . Если есть конкретные вопросы — обращайтесь.

А>Мне нужно максимально простое решение с точки зрения архитектуры. Чтобы допустим, при добавлении задачи: "загрузка сигнатур", это не затрагивало задачу "проверка файла".


Поток обхода дерева файлов их обходит. Для каждого найденного файла он передает его путь объект — "аккумулятор задач". N потоков-обработчиков в цикле обращаются к аккумулятору задач с запросом "дай задачу". Аккумулятор задач на запрос "дай задачу" отдает путь к файлу и что с ним надо делать — сигнатуры там читать или что. Соответственно пауза реализуется через команду аккумулятору задач "пока больше задач не давать". Ну и можно еще поток обхода файловой системы на паузу поставить, чтобы диском не вертел.

Это одно из примитивнейших решений "в лоб". В зависимости от требований можно и пул потоков прикрутить, и по другому сделать.
Re: Многопоточность и архитектура. Объясните простые вещи.
От: __kot2  
Дата: 17.06.11 06:10
Оценка: 2 (1) +1
я не думаю что дисковые операции станут быстрее если их делать из нескольких потоков. скорее всего медленней.
единственная задача которую можно распараллелить это проверка файлов. да и сначала лучше сделать в одном потоке все.
Re[2]: Многопоточность и архитектура. Объясните простые вещи
От: Аноним  
Дата: 17.06.11 07:52
Оценка:
Здравствуйте, __kot2, Вы писали:

__>я не думаю что дисковые операции станут быстрее если их делать из нескольких потоков. скорее всего медленней.

__>единственная задача которую можно распараллелить это проверка файлов. да и сначала лучше сделать в одном потоке все.

Распараллеливать собирался на этапе чтения файлов. Ну думаю и это, в тот же поток правильней будет, чтобы диск не мучать.
Суть, что еще к "читателям" прибавиться чтение, куки, реестра, памяти. => Делаем один пул для читателей и один для сканеров.

Есть еще пересекающиеся задачи — загрузка сигнатур. Их видимо в отдельный пул загрузчиков.
Итого, как весь этот зоопарк сделать гибким при этом потоко-безопасным, и простым?? Поглядел в сторону аспектно-ориентированного, пока ничего не понял...

Вроде такого:
Имеем три типа задач, 2 рид онли — чтение,сканирование, 1 — загрузчики сигнатур. =>3 пула потоков. Уже упростили. Теперь остался вопрос,
взаимодействия — сканер<->данные. Локеры, multi-reader single-writer — хорошо. Как это с точки зрения АОП может выглядеть?? Чистый С++ и WinApi.
Re[3]: Многопоточность и архитектура. Объясните простые вещи
От: __kot2  
Дата: 17.06.11 07:56
Оценка: +1
Здравствуйте, Аноним, Вы писали:
А>Распараллеливать собирался на этапе чтения файлов. Ну думаю и это, в тот же поток правильней будет, чтобы диск не мучать.
А>Суть, что еще к "читателям" прибавиться чтение, куки, реестра, памяти. => Делаем один пул для читателей и один для сканеров.
ой, навороты какие-то. не надо никаких читателей. все пусть в одном потоке делается. попробуйте просто копирование параллельно двух разных файлов запустить с диска — он как трещотка трещать начнет все время головку перепозицинирую и тормозить будет страшно.

А>Есть еще пересекающиеся задачи — загрузка сигнатур. Их видимо в отдельный пул загрузчиков.

трещотка будет

А>Итого, как весь этот зоопарк сделать гибким при этом потоко-безопасным, и простым?? Поглядел в сторону аспектно-ориентированного, пока ничего не понял...

А>Вроде такого:
А>Имеем три типа задач, 2 рид онли — чтение,сканирование, 1 — загрузчики сигнатур. =>3 пула потоков. Уже упростили. Теперь остался вопрос,
какое аспекто-отриентированное? зачем задачи? зачем загрузчики? зачем столько гемора? задача элементарно в лоб делается. распараллеливать смысл имеет только проверки.
Re[2]: Многопоточность и архитектура. Объясните простые вещи
От: Аноним  
Дата: 17.06.11 08:12
Оценка:
Здравствуйте, Eye of Hell, Вы писали:

А>>Почему во всех реализациях пулов потоков, нет простых операций: Pause, Resume, Stop, OnTaskStart, OnTaskEnd?


EOH>Потому что пул потоков — это низкоуровнивый примитив. Не такой низкоуровнивый как "поток" или "объект синхронизации типа event", но примитив. Сам по себе он, увы, ничего не может. То что вы хотите — это уже "движок программы". Который пишется с использованием примитивов. Можно с помощью пула потоков, можно с помощью просто потоков и примитивов синхронизации. А уж у самого движка есть и Pause, и Resume, и OnTaskStart, и аже onTaskEnd. Как раз недавно такой писал . Написать такой движок не очень сложно, в зависимости от используемых библиотек это 50-500 строк. Я на Qt где-то в 100 уложился.


Так все же, как по вашему организовать поступление событий Pause, Resume? Просто сохранить состояние потока и данных при паузе, и восстанавливать при продолжение.
Ну если не мудрить, то просто Suspend(CurrentThread) внутри объекта задачи?? Я до конца не понимаю, что происходит при прерывании потока например посреди выполнения функции..

А>>Как это реализовать просто и расширяемо? Как работает SetEvent? Мы его создаем CreateEvent, и ждем WaitForSingleObject. Когда нужно выполнить задачу в пуле,

А>>делаем SetEvent, что происходит в этот момент??

EOH>Ну это как бы надо почитать документацию по используемому вами языку и фреймворку. Вы же не надеетесь, что вам тут зачитают лекцию по языку программирования, его библиотекам и по мультипоточному программированию? . Если есть конкретные вопросы — обращайтесь.


С++ и WinApi. Подумываю прикрутить boost, ради реализации threadpool, но по мне так избыточно. От того и столько вопросов. в буст реализации только 2 операции "добавить в очередь" и "ждать-пока", впрочем как и в .NeT. Ну
там колбэки еще. Мне нужно знать момент завершения задачи, чтобы перенаправить данные другому пулу.

А>>Мне нужно максимально простое решение с точки зрения архитектуры. Чтобы допустим, при добавлении задачи: "загрузка сигнатур", это не затрагивало задачу "проверка файла".


EOH>Поток обхода дерева файлов их обходит. Для каждого найденного файла он передает его путь объект — "аккумулятор задач". N потоков-обработчиков в цикле обращаются к аккумулятору задач с запросом "дай задачу". Аккумулятор задач на запрос "дай задачу" отдает путь к файлу и что с ним надо делать — сигнатуры там читать или что. Соответственно пауза реализуется через команду аккумулятору задач "пока больше задач не давать". Ну и можно еще поток обхода файловой системы на паузу поставить, чтобы диском не вертел.


EOH>Это одно из примитивнейших решений "в лоб". В зависимости от требований можно и пул потоков прикрутить, и по другому сделать.


Пока только перебираю варианты. Цель — сделать архитектуру сканера максимально просто. Чтобы завершение одной задачи — порождало другую. Суть чтение->анализ. 2 разных пула+Данные.
Re[3]: Многопоточность и архитектура. Объясните простые вещи
От: Eye of Hell Россия eyeofhell.habr.ru
Дата: 17.06.11 10:52
Оценка:
А>Так все же, как по вашему организовать поступление событий Pause, Resume? Просто сохранить состояние потока и данных при паузе, и восстанавливать при продолжение.
А>Ну если не мудрить, то просто Suspend(CurrentThread) внутри объекта задачи?? Я до конца не понимаю, что происходит при прерывании потока например посреди выполнения функции..

Способов много. Делать суспенд потокам — не очень хорошая идея, это сильно аппаратно зависимо. Гораздо проще сделать паузу у двух объектов — того, который выдает задачи и который аккумулирует результаты. Ставим их оба на паузу (первый перестает задачи выдавать, второй перестает отдавать результаты) и у нас есть пауза. А то, что какой-то поток в это время читал из файла, успешно считает и что-то сделает — нам не критично, потому что результат он передаст объекту, собирающему результаты, а тот — на паузе и никуда дальше результат не отдаст пока с паузы не снимут.
Re[3]: Многопоточность и архитектура. Объясните простые вещи
От: -VaS- Россия vaskir.blogspot.com
Дата: 29.06.11 04:31
Оценка:
Посмотрите, как сделано в .NET 4 Parallel Extensions (если пишите под .net, то просто используйте их). Там как раз есть таски, есть выстраивание их в цепочку, есть джойны тасков, есть механизм отмены, контроль количества потоков (вот эту пачку тасков делаем в 1 поток, а вот эту — в 5. При этом используется один пул) и даже визуальный отладчик
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.