| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Для новичков > Потоки и события |
| Автор: Dom 7.12.2008, 23:00 | ||
| Первый опыт работы с потоками. Случай конечно не самый простой. Простые уже рассмотрел и вроде как чуток разобрался. Тем кто посоветует классиков сразу скажу - Петровича читал, и по форуму лазил, ну и в инете само собой. Белые пятна присутствуют, но среди них есть и островки знаний. То что в приведенном ниже коде возможно каша, можно нне упоминать. Лучше просто указать где и как от нее избавиться хотя бы. Итак, приступим. Есть программа, в которой можно построить набор матмоделей №1 (или вообще всего одну). Каждая матмодель включает в себя набор других моделей №2 попроще что ли (их число может быть очень большим). Расчет моделей №2 происходит независимо друг от друга, все что у них есть общего это обращение к единому блоку с данными. Т.е. на лицо случай, когда параллельное вычисление этих моделей №2, должно дать существенный прирост в производительности на много ядерных (многопроцессорных) системах в первую очередь. Цель такова - строить модели №2 каждую в отдельном потоке. По возможности одновременно должно запускаться не слишком большое число потоков (пока не могу понять как это реализовать, возможно через семафоры, а?), т.к. их возможное число может быть свыше тысячи. Т.е. хорошо бы задавать максимально число одновременно активных потоков. После расчета всех моделей №2 должен следовать этап расчета их статистики в рамках более общей модели №1, в которую они входят. Т.е. в этом случае надо дождаться пока все потоки завершат свою работу, затем расчитать статистику получившейся общей модели №1, затем запустить построение следующей матмодели №1. Покажу на схематичном примере, первую попытку реализации вышеизложенного. Есть глобальная переменная ThreadsCount, которая содержит число существующих потоков. Есть событие EndCalcEvent, которое по идее должно срабатывать когда число существующих потоков становится равным нулю. Из главной формы запускается процедура постоения матмоделей №1 (определены как F). Создаем первый объект F и запускем процедуру вычислений, которая состоит из расчета большого числа отдельных небольших моделей №2 (обозначены как Т). Создаем нужное число моделей Т, одновременно создаем соответствующие им потоки, производим настойки потоков и запускаем их. В тестовом режиме запускал таким образом, чтобы число объектов Т было равно 1. После этого дебаг переходит на строку if EndCalcEvent.WaitFor(INFINITE) = wrSignaled. А затем попадаем в сам поток. В котором все происходит все корректно, до момента синхронизации полученных результатов. После перехода на строку Synchronize(Update) жму Ф7 или Ф8 и все, дальше непонятно что происходит, в процедуру Update не заходит. Просто стоит и ждет чего-то. Есть подозрение что намудрил чего-то с событиями. Если вместо EndCalcEvent.WaitFor(INFINITE) написать EndCalcEvent.WaitFor(20000), то через какое-то время ни с то ни с сего запускается F.CalcStat (при чем брейкпоинт стоящий на этой строке не срабатывает, зато вываливается ошибка расчета, т.к. объект F по сути еще пустой). После чего я попадаю в процедуру Update потока. Delphi 7
Если код малопонятен или безграмотен, то может кто-то предложит хотя бы алгоритм реализации того что описано выше? Вкратце. Требуется одновременный запуск ограниченного числа потоков, чтобы при завершении одного потока начинал работать следующий. И чтобы программа ожидала окончания работы всех потоков, и лишь потом обрабатывала полученые результаты все вместе. После чего запускала всю процедуру по новой. И еще такой момент - хорошо бы, чтобы главное окно приложения в время вычисления потоков реагировало бы на действия пользователя. Буду благодарен любым конструктивным советам и подсказкам, а то замучился уже. Советы читать маны неактуальны, т.к. именно этим и занимаюсь. ЗЫ, Понимаю, что одна тема - один вопрос. Но процедура ТEvent.WaitFor вызывает остановку потока, в котором она вызывается? Т.е. если ее вызывать в главном потоке, то главная форма приложения зависнет тоже? |
| Автор: Dom 8.12.2008, 11:21 | ||
Про зависание главного потока после вызова TEvent.WaitFor догадался. Т.е. эта процедура и для потока и для события действует одинаково - погружая поток в ожидание, так?
|
| Автор: CodeMonkey 8.12.2008, 11:28 | ||
В том-то и дело, что по-разному. У объекта "событие" WaitFor погружает поток в безусловное ожидание события. У потока - нет. Я вам и подсказал посмотреть реализацию WaitFor потока. Рекомендую пройти http://www.delphikingdom.ru/quintana/quintana.asp?ItemID=14 ;) Может ещё будет интересно http://forum.sources.ru/index.php?showtopic=252937. |