| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: WinAPI и системное программирование > Потоки, организация |
| Автор: bagos 2.2.2009, 06:11 |
| Написал программу, которая выполняет ряд некоторых функций. Одни из которых это - связь с сайтом и получение от него определенной информации, анализ полученной информации, проверка наличия новых данных на том же сайте и их загрузка. Необходимо реализовать работу функций программы с использованием потоков. Более подробное описание задачи потоков: При старте программы возможны два варианта: (А).Программа запускается впервые,поэтому запускается поток ThrStartFirst. Этот поток скачивает с сайта страницу, парсит нужные данные и добавляет их в более расширенный компонент listbox(у листбокса есть свойства text,text1,text2,text3). В то время как работает ThrStartFirst, запускается следующий поток ThrStratAnalys, который берет по очереди каждый итем листбокса, вытаскивает свойство text и скачивает страницу с интернета, уже анализируя полученные данные и сохраняя в определенной структуре в файл.В это же время должен работать еще один поток ThrUpdate. Он скачивает всю туже страницу и наблюдает за появлением новых данных,удалением тех которые уже удалены с той страницы в интернете, и изменением каких то данных.( запускаться поток должен через определенное заданное время) Вариант (В). Программа запущенна не впервые. В листбокс заносятся данные из сохраненных файлов(учитывая что вариант А полностью отработал в предыдущей загрузке, если нет то скачиваются файлы, которые не были скачаны в пером запуске А). Как только данные занесены, а это происходит весьма быстро так как файлы находяятся на диске в формате txt, то запускается поток ThrUpdate, выполняет те же операции что и в варианте А. Идеально было, если б таких ThrUpdate было больше одного(т.е.ThrUpdate1,2,3,4... которые выполняли свои функции с данными, не обязательно изменявшие данные в листбоксе). Изучал работу критических секций,мьютексов, семафоров и других вариантов синхронизации (то что выложил Петрович). Но понять пока еще трудно. Надеюсь на помощь в создании алгоритмов. Надеюсь услышать советы: что лучше использовать в моем случае, на что обратить внимание. P.S. Программа будет работать с моим сайтом. Для скачивания содержимого страниц используется idhttp. Заранее благодарен. |
| Автор: bagos 3.2.2009, 20:43 |
| Сейчас посылаю мэйнтреду сообщение, в котором передаю указатель на record, тот его обрабатывает и все норм. Хочу попробовать сделать через onterminate. Т.е. в мэйнтреде создаю procedure HandleOnTerminate(Sender:TObject); MyThread.OnTerminate := HandleOnTerminate; procedure TForm1.HandleOnTerminate(Sender:TObject); begin тут нужно описать принятие данных,но как это будет выглядеть? куда в потоке записывать данные чтобы потом их можно было в этой процедуре обработать? end; |
| Автор: MetalFan 3.2.2009, 22:43 | ||
например через поле класса-потока. |
| Автор: bagos 3.2.2009, 23:08 | ||
Сделал так:\
утечки памяти не будет? |
| Автор: MetalFan 4.2.2009, 12:29 |
молодцом! утечка будет в строке 23. з.ы. ты бы еще меньше кода привел, чтобы все сразу в телепаты записались. |
| Автор: bagos 5.2.2009, 03:51 | ||
Вот два юнита. В таймере последующие разы поток не запускается, со временем все нормально, почему то not assigned(potok) возвращает что поток вроде как есть. хотя freeonterminate = true; в чем дело? Хочу сделать чтобы после первого запуска поток, в следующие разу он запускался через 5 сек.
|
| Автор: Felan 5.2.2009, 07:43 | ||||||
Во первых
не правильно, а правильно
Во вторых, поток нельзя запустить снова, после того, как он завершен. Поток либо есть, либо нет. Если он есть, то он может быть остановлен, но не закончен. Инными словами, если ты используешь TThread то тебе надо в методе execute организовать цикл между итерациями которого будет 5 сек. Тогда получится то, что ты хочешь. Вообще поищи в сети книгу "Многопоточность - как это делается в Delphi". Очень хороша. Тебе надо что-то типа такого:
Где TPinger = class(TThread). ЗЫЖ Ну это кусочки из рабочего проекта... весь не могу привести, но вроде должно быть понятны основные идеи. |
| Автор: bagos 5.2.2009, 09:13 |
| Спасибо! Сразу вопросы появились: Чем отличается wm_user от wm_app я так и не понял, ведь оба выполняют одну и туже функцию wm_...+X ? Поток нельзя запустить снова, после того, как он завершен. Поток либо есть, либо нет. Если он есть, то он может быть остановлен, но не закончен. Непонятно почему, что мешает мне запустить его снова? А если рассматривать вариант что приложение будет работать 24 часа в сутки, то поток будет работать тоже постоянно? и закончит свою работу только при выходе из программы? |
| Автор: bagos 5.2.2009, 11:47 |
| Приведите пожалуйста небольшой пример, как организовать доступ к listbox несколькими пишущими и читающими потоками с использование postmessage. (критические секции?). Допустим Один добавляет итем, а другой ищет определенный итем и удаляет его или изменяет. Добавлено через 42 секунды Видел примеры работы с критическими секциями, так там идет обращение к vcl прямо внутри секции! |
| Автор: Felan 5.2.2009, 11:50 | ||||||||
Хм... ну можно и так сказать... счас еще раз прочитал в MSDN, че-то мутновато как-то... Типа если окно само себе посылает сообщение или внутренним окнам, то надо от WM_USER плясать, а если в оконную процедуру шлется сообщение извне, но в пределах самого же приложения то от WM_APP... Посути получается, что WM_APP это сообщения которые должны посылаться окну приложения из самого же приложения, а для всех остальных должно быть WM_USER. Или я чего не так понял?
Че за моменты? Валяй, вдруг правда че подправить надо ЗЫЖ Думаю оффтопиком не будет, т.к. автору тоже про это надо послушать. Добавлено через 4 минуты и 39 секунд
Ну это, я надеюсь мы сейчас с MetalFanом выясним.
То, что ты не сможешь его "запустить снова". Нужно будет заново создать класс. Если надо что бы он работал 24 часа в сутки, то надо делать цикл, который будет выполняться эти самые 24 часа. При этом ему не обязательно работать постоянно. Его можно приостановить. Но если ты его завершишь, то все, надо будет делать заново. Это в больше степени отностися к TThread. Если делать на API там немного подругому, но суть та же, если поток завершился (произошел выход из поточной процедуры), то его (поток) надо создавать заново. |
| Автор: bagos 5.2.2009, 12:04 |
| Опа, извиняюсь, неправильно сказал. Не запустить, а создать |
| Автор: bagos 5.2.2009, 12:28 | ||
Можно обращаться к форме как здесь?
|