Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Очередь потоков


Страницы:   1 2

DevilDevil ©   (2012-07-23 16:57:00) 

Здравствуйте уважаемые мастера

Существует задача, которую необходимо распараллелить на несколько процессоров. Для этого планируется создать очередь потоков, количество потоков = количеству ядер.

В цикле (основной поток):
- собираем некоторую инфо
- ждём первый освободившийся поток
- кидаем ему инфо и адрес куда он должен записать результат

Ну и соответственно когда всё инфо считанно:
- ждём обработки всех потоков
- удаляем все потоки

Что интересует
Вообще я иногда программирую потоки, но уверенного владения ими нет и нет уверенности, что я всё делаю правильно. Во-первых, интересует, как узнать количество ядер. Во-вторых, интересует, как грамотнее организовать эту очередь потоков. Ну и в-третьих, интересны толковые статьи по программировании потоков, чтобы как можно меньше было воды и как можно больше сути


Сергей М.   (2012-07-23 20:37:00) [21]


> не лучше ли доверить распределение потоков по ядрам ОС ?


А зачем тогда вообще задумываться про "ядра" ?


Anatoly Podgoretsky   (2012-07-23 19:10:00) [22]

GetProcessAffinityMask
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683213(v=vs.85).aspx


DevilDevil   (2012-07-23 18:53:00) [23]

> Медвежонок Пятачок ©   (23.07.12 18:48) [8]

перезадай вопрос корректно


Медвежонок Пятачок   (2012-07-23 18:48:00) [24]

- ждём первый освободившийся поток

Вот нахрена спрашивается?


DevilDevil   (2012-07-23 18:42:00) [25]

> Юрий Зотов ©   (23.07.12 18:09) [5]
> То есть, главный поток создает не очередь потоков, а очередь
> кусков. А далее см. [1].


Мне кажется это приведёт к дополнительному расходу памяти. Эффективнее думаю, сделать как описал в [0]:
В цикле (основной поток):
- собираем некоторую инфо, получаем кусок
- ждём первый освободившийся поток
- кидаем ему кусок и адрес куда он должен записать результат

Ну и соответственно когда всё инфо считанно:
- ждём обработки всех потоков
- удаляем все потоки


Исходный кусок занимает в среднем в 4 раза больше, чем инфо. А результирующий кусок в среднем в 6 раз меньше чем инфо. То есть в 24 раза )

Именно очередь потоков.
Но как:
- организовать очередь и синхронизировать её
- поток должен сигнализировать что он "освободился"
- запустить поток в работу после ожидания своей очереди


Юрий Зотов   (2012-07-23 18:19:00) [26]


> DevilDevil ©   (23.07.12 17:57) [4]

Чтобы было проще.

Очередь - это покупатели у входа в магазин. Главный поток - это поток прибывающих в эту очередь. Дополнительные потоки - это продавцы. Освободившись от одного покупателя, продавец идет за следующим.


Юрий Зотов   (2012-07-23 18:09:00) [27]


> DevilDevil ©   (23.07.12 17:57) [4]
> Предполагается сделать так, чтобы главный поток осуществлял
> чтение исходных кусков и перенаправлял их обработку на потоки.

То есть, главный поток создает не очередь потоков, а очередь кусков. А далее см. [1].

Главный поток добавляет куски в очередь. Каждый дополнительный поток берет себе кусок, удаляет его из очереди и обрабатывает. Закончив обработку, снова смотрит очередь. Если она не пустая, то все повторяется, а если пустая - поток умирает. Когда умрут все потоки, программа завершается.

Очередь, конечно, должна быть синхронизирована.


DevilDevil   (2012-07-23 17:57:00) [28]

Допустим имеется файл.
Допустим если прочитать его в память, проанализировать - получается 1000 кусков данных.

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

Сейчас 1 главный поток обрабатывает информацию, получает кусок данных и перерабатывает этот кусок данных в алгоритме.

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

Слушаю предложения по реализации

> Сергей М. ©   (23.07.12 17:08) [2]
обязательно ли явно привязывать SetThreadAffinityMask, не лучше ли доверить распределение потоков по ядрам ОС ?


MsGuns   (2012-07-23 17:34:00) [29]

Если у Вас потоки чего-то там ждут (особенно "команд") из главного потока, то ИМХО, у Вас совершенно неверное представление об их предназначении


Сергей М.   (2012-07-23 17:08:00) [30]


> как узнать количество ядер


GetProcessAffinityMask()


> как грамотнее организовать эту очередь потоков


У каждого потока уже есть своя индивидуальная очередь, и не одна.

Очередь заданий на асинхронное выполнение пользовательских процедур управляется вызовами QueueUserAPC.

Очередь пользовательских сообщений потоку и принадлежащим ему окнам управляется асинхронными вызовами PostThreadMessage() и PostMessage() соответственно.

В простейшем случае будет достаточно создать по одному потоку на доступное процессу ядро, "привязать" поток к ядру (SetThreadAffinityMask) и раздавать потокам задания пропорционально планируемым их нагрузками.


Медвежонок Пятачок   (2012-07-23 17:05:00) [31]

- ждём первый освободившийся поток
- кидаем ему инфо и адрес куда он должен записать результат


Все верно, только все наеборот.
Первый освободившийся идет к раздаче и получает свою новую порцию работы.
Когда он ее выполнит, то идет снова к раздаче.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо