|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
23.08.2016, 21:39 | #1 |
Форумчанин
Регистрация: 02.08.2014
Сообщений: 476
|
Дождаться завершения всех потоков
Доброго времени суток!
Имеется проблема, не могу придумать решение, вот в чем суть: имеется несколько потоков, 5 штук допустим, в каждом потоке собираются ссылки, и количество этих ссылок всегда разное, собираются они ругулярками, потом в цикле с каждой такой ссылкой запускается еще один поток и парсит со страницы цифры, вот нужно сначала спарсить цифры с каждой страницы, а потом их все сложить, в голову только приходит объявить глобальную переменную (и даже не одну, так как основных потоков как мы помним у нас 5) и в каждом потоке её увеличивать, но опять же как потом это все сложить, как узнать какой поток последний соберет эти цифры, и вообще идея с глобальной переменной мне не очень нравится, может кто подскажет как решить эту проблему? |
23.08.2016, 22:43 | #2 |
Участник клуба
Регистрация: 21.10.2015
Сообщений: 1,361
|
пул потоков
|
23.08.2016, 22:48 | #3 |
Форумчанин
Регистрация: 02.08.2014
Сообщений: 476
|
|
23.08.2016, 22:54 | #4 |
Участник клуба
Регистрация: 21.10.2015
Сообщений: 1,361
|
вы бы хоть написали какая делфи у вас, а то есть большая разница
|
24.08.2016, 00:44 | #5 |
Форумчанин
Регистрация: 02.08.2014
Сообщений: 476
|
|
24.08.2016, 18:16 | #6 | |
Старожил
Регистрация: 26.04.2008
Сообщений: 2,645
|
А чем не устраивает глобальная переменная? То, что глобальные переменные - зло в эпоху мультипотоков, так это для внутренней структуры. А для совместной работы потоков без этого порой никуда. Этот форум тому пример, в одну эту тему (глоб переменная) отписались разные пользователи (потоки) и ничего, форум не рухнул )) Главное синхронизировать.
Пусть в классе формы есть некий счётчик (переменная с именем ThisGlobalVar_Warning_Warning), который потоки увеличивают через методы синхронизации (операция изменения счётчика относительна быстра по отношению к вэб-серфингу и парсингу и не повлияет на визуализацию, скорость работы потоков). Этот метод прост, быстр (в плане кода по крайней мере) и суров. Если не устраивает такой подход, то есть несколько других вариантов - сообщения или сигналы, например. Пусть форма ждёт какого-нибудь, например, SendMessag'а и при получении увеличивает счётчик. Хотя, и тут переменную лучше объявлять глобальной для класса формы, иначе впоследствии прочитать её можно будет только с компонента на который вывелась инфа (или через какую-нибудь функцию/механизм и т.п.), а напрямую не получится. Цитата:
А вот если бы задача стояла другая - например, обрабатывать бОльшие объёмы данных, то идея с глобальной переменной была бы уже не такой хорошей. |
|
24.08.2016, 19:03 | #7 | ||
Форумчанин
Регистрация: 02.08.2014
Сообщений: 476
|
Цитата:
Цитата:
|
||
24.08.2016, 19:53 | #8 |
Лис
Старожил
Регистрация: 18.09.2015
Сообщений: 2,409
|
Тут вариантов куча.
1) Смотри потоко безопасную очередь. Признаком конца является пустая очередь. 2) Делать боса который будет распределять задачи по свободным потокам. Переодически проверяет свободны потоки или нет. 3) Делать диспетчера. Потоки посылают сообщения. Диспетчер быстро нагружает рабочего и засыпает. Сообщения всегда синхронны. Как обойтись без глобальной переменной? Вот пример, чуть до делать и будет пункт 2. Бос ждет пока все потоки рабочих не завершаться. Код:
Пул потоков? Это да можно и его использовать.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал . |
24.08.2016, 20:09 | #9 | |
Старожил
Регистрация: 26.04.2008
Сообщений: 2,645
|
Цитата:
Для любого из этих вариантов можно вести учёт потоков (легко организовать свой так называемый пул через TThreadList). При создании потока, пусть он добавляется в один из пяти TThreadList, смотря кто был его прародителем (TThreadList может быть глобальной переменной, кстати, не требующей ручной синхронизации), а по завершению удаляет себя от туда. Тогда мы всегда будем знать пуст ли каждый из 5-ти списков потоков или нет. Только в TThreadList нужна сначала добавить потомка, а потом уже удалять родителя, иначе, пусть даже на доли секунды, TThreadList может оказаться пустым, что может посчитаться как завершение всех потоков |
|
24.08.2016, 21:02 | #10 |
Форумчанин
Регистрация: 02.08.2014
Сообщений: 476
|
Смотрите вообщем какая задача, постараюсь более подробно объяснить, у меня есть 4 listview, в каждый должны будут вывестись данные, есть так же 4 потока / 4 основных ссылки, 4 абсолютно одинаковых потока, я запускаю каждый, передаю в него эту основную ссылку, поток делает GET запрос на сайт, вытаскивает от туда ссылки их может быть сколько угодно, но не больше 10 (имеется ввиду в каждом из 4 потоков), с каждой такой ссылкой создается еще один поток, в него передается эта ссылка, от туда я парсю цифры, мне их нужно сложить со всеми остальными этими 10 потоками (ну или меньше) и потом эти цифры нужно вывести в нужный listview. Надеюсь понятно объяснил задачу.
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Дождаться завершения работы процедуры | Shouldercannon | Общие вопросы Delphi | 3 | 13.11.2013 14:09 |
Дождаться завершения работы командной строки | ivt22 | Общие вопросы Delphi | 21 | 01.11.2013 11:59 |
Дождаться завершения другой программы в консоле delphi | SawaMEN | Общие вопросы Delphi | 4 | 09.09.2013 14:26 |
Как дождаться завершения запущенного приложения | DennerV | Win Api | 5 | 13.08.2010 13:48 |
Как дождаться завершения процедуры? | Hintman | Win Api | 6 | 14.10.2009 14:46 |