![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| Vitus28 |
|
||||||||
|
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 20.3.2014 Репутация: нет Всего: нет |
Доброго всем времени суток!
Возникла такая проблема. Имеется большой массив данных (примерно 2000 записей, количество каждый день увеличивается). Каждую запись из массива нужно обработать. Для ускорения этого процесса (2000 записей обрабатываются примерно 12часов) решил раскидывать записи между потоками. И тут возникла проблема, переменная объявленная для потока (для хранения ID) затирается при создании следующего потока. Думаю что с исходниками и результатом работы все станет яснее. На главной форме есть Button и Memo. При нажатии на кнопку запускается "основной поток"
модуль основного потока:
модуль дочернего потока:
Суть такова. В "главном потоке" находится массив который нужно обработать (for i:=1 to 5 do) и имеется массив дочернего патока (ну допустим на 3 единицы). Т.е. бегая по основному циклу я ищу какой из этих трех дочерних потоков отработал и запускаю его на очередную запись. Чтобы поток знал что он вообще обрабатывает при объявлении у него указана переменная Number. Вот результат:
Дочерний 1 запустился, затем 2, затем 3. А потом Дочерний поток 2 остановлен и снова Дочерний поток 2 остановлен. Как быть, жду Ваших вариантов и предложений! Исходники по ссылке Это сообщение отредактировал(а) Vitus28 - 10.4.2014, 09:57 Присоединённый файл ( Кол-во скачиваний: 0 )
code.rar 8,02 Kb |
||||||||
|
|||||||||
| Poseidon |
|
|||
![]() Delphi developer ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 5273 Регистрация: 4.2.2005 Где: Гомель, Беларусь Репутация: 53 Всего: 133 |
Я лишь укажу на очевидные ошибки. Если не поможет, то нужно уже смотреть детально.
Если бегло посмотреть, то получается следующее: в TChildThread.Execute в потоке 1 выполняется строка text1:='Дочерний поток ' + IntToStr(Number) + ' остановлен'; В text1 у нас "Дочерний поток 1 остановлен". Затем тут же в потоке 2 выполняется эта же строка. В text1 у нас уже "Дочерний поток 2 остановлен". Затем в первом потоке выполняется Synchronize(Result) и в memo записывается то, что в text1, а там у нас уже "Дочерний поток 2 остановлен". Потом во втором потоке выполняется Synchronize(Result) и в memo снова записывается "Дочерний поток 2 остановлен". Вообще при работе с несколькими потоками нужно быть внимательнее при использовании глобальных переменных (а правильно вообще не использовать ничего глобального). -------------------- Если хочешь, что бы что-то работало - используй написанное, если хочешь что-то понять - пиши сам... |
|||
|
||||
| PointerToNil |
|
|||
![]() Профиль Группа: Участник Сообщений: 108 Регистрация: 17.6.2013 Репутация: 3 Всего: 6 |
1. вроде бы, "главный" поток процессор не занимает (лишь распределяет задачи), но занимается выводом на форму через synchronize (ужас!)
=> он абсолютно НЕ НУЖЕН, с этим отлично справится основной (VCL) поток 2. вы пишете "В "главном потоке" находится массив который нужно обработать" данные не НАХОДЯТСЯ в потоках! потоки лишь исполняют инструкции! для потоков все данные как бы глобальные (ну, кроме threadvar), только программист может себя ограничить тем, что просто не обращается в потоке к "чужим" данным (ограничивается полями объекта текущего потока). ОБЪЕКТ потока - это тоже данные и они только номинально связаны с конкретным ПОТОКОМ ИСПОЛНЕНИЯ инструкций из T{My}Thread.Execute 3. я бы ввел глобальную переменную (лучше - поле формы и т.п.) "номер последней уже взятой на обработку записи", каждый освободившийся дочерний поток увеличивал бы её через interlockedincrement и начинал этой записью заниматься, пока все не исчерпаются (без всяких остановок) никаких synchronize и никаких sleep в дочерних основной поток может следить за ходом работ через ту же глобальную переменную (в нем может быть и sleep) |
|||
|
||||
| Vitus28 |
|
||||||
|
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 20.3.2014 Репутация: нет Всего: нет |
Poseidon,
с этим согласен (попутал) - но по факту особо ни на что не влияет
попробовал предоженный варинат - без изменений Хотел сказать что приведенный пример - это облегченный и упрощенный вариант задачи, которую я решаю. Что бы не нагружать его кодом был сделан произвольный цикл, sleep используются только для того чтобы сделать задержку выполнения. И сразу поясню. Я понимаю что когда запускается программа на исполнения создается основной (главный) поток программы. В своём описании под "главным потоком" я понимаю первый поток (модуль основного потока), в котором у меня находится цикл по данным. В этом потоке я создаю мной названные "дочерние потоки", которые призваны уменьшить время требуемое для обработки инфы. PointerToNil,
В моем "главном потоке" (не путать с главным или основным потоком самого приложения. "Главным" назвал его я, можно назвать master или как душе угодно) из файла xls читываются, проверяются данные ip, url, domain. ip нужно раза 2-4 пингануть, url проверить на доступность, и ели он доступен по трассирнуть. Этим как раз я и хочу озадачить дочерние потоки (их количество будет регулироваться настройкой), в приведенном примере их 3. Ну вот как-то так. Решение пока не надено, пробую различные варианты, жду Ваших предложений |
||||||
|
|||||||
| Vitus28 |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 15 Регистрация: 20.3.2014 Репутация: нет Всего: нет |
Poseidon,
Когда пробовал первый раз видимо что-то намутил. Сейчас закинул переменные text и text1 в переменные потока и все стало замечтательно Всем болшое спасибо за помощь! Это сообщение отредактировал(а) Vitus28 - 11.4.2014, 09:05 |
|||
|
||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |