![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Организация работы потоков
Тимоха © (2009-02-02 08:20:00)Написал программу, которая выполняет ряд некоторых функций.
Одни из которых это - связь с сайтом и получение от него определенной информации, анализ полученной информации, проверка наличия новых данных на том же сайте и их загрузка.
Необходимо реализовать работу функций программы с использованием потоков.
Более подробное описание задачи потоков:
При старте программы возможны два варианта:
(А).Программа запускается впервые,поэтому запускается поток ThrStartFirst. Этот поток скачивает с сайта страницу, парсит нужные данные и добавляет их в более расширенный компонент listbox(у листбокса есть свойства text,text1,text2,text3). В то время как работает ThrStartFirst, запускается следующий поток ThrStratAnalys, который берет по очереди каждый итем листбокса, вытаскивает свойство text и скачивает страницу с интернета, уже анализируя полученные данные и сохраняя в определенной структуре в файл.В это же время должен работать еще один поток ThrUpdate. Он скачивает всю туже страницу и наблюдает за появлением новых данных,удалением тех которые уже удалены с той страницы в интернете, и изменением каких то данных.( запускаться поток должен через определенное заданное время)
Вариант (В). Программа запущенна не впервые. В листбокс заносятся данные из сохраненных файлов(учитывая что вариант А полностью отработал в предыдущей загрузке, если нет то скачиваются файлы, которые не были скачаны в пером запуске А). Как только данные занесены, а это происходит весьма быстро так как файлы находяятся на диске в формате txt, то запускается поток ThrUpdate, выполняет те же операции что и в варианте А. Идеально было, если б таких ThrUpdate было больше одного(т.е.ThrUpdate1,2,3,4... которые выполняли свои функции с данными, не обязательно изменявшие данные в листбоксе).
Изучал работу критических секций,мьютексов, семафоров и других вариантов синхронизации. Но понять пока еще трудно. Надеюсь на помощь в создании алгоритмов. Надеюсь услышать советы: что лучше использовать в моем случае, на что обратить внимание.
P.S. Программа будет работать с моим сайтом. Для скачивания содержимого страниц используется idhttp.
Заранее благодарен.
Тимоха (2009-02-04 01:01:00) [21]А если рассматривать с точки зрения что потом я собираюсь синхронизировать треды?
Eraser (2009-02-04 01:00:00) [22]> [93] Тимоха (03.02.09 21:43)
> При таком варианте утечки памяти не будет?
нужно запомнить одно золотое правило - память надо освобождать там же, где и выделять... по возможности.
если сейчас есть уверенность в том, что окно, которому предназначается сообщение существует, то ситуация со временем может поменяться, а код останется.
есть два варианта.
1.
New(mess);
try
// send message
finally
Dispose(mess);
end;
предпочтительный:
выделять память для сообщения в стеке.
Медвежонок Пятачок (2009-02-04 00:41:00) [23]это вопрос мировоззрения и вкуса
Тимоха (2009-02-04 00:26:00) [24]Объясните пожалуйста что использовать лучше и почему? sendmessage или onterminate для получения данных с треда?
Тимоха (2009-02-03 21:43:00) [25]Сделал так:
В рабочем треде создаю TList,List_count.
try
New(mess);
List.Add(mess);
Inc(List_count);
mess.tema := Copy(page, index_tema + 7, count_tema - index_tema - 7);
mess.name := Copy(page, index_name + 9, count_name - index_name - 9);
finally
end;
в HandleOnTerminate в мэйнтреде:
try
for i := 0 to potok.List_count - 1 do
begin
mess := potok.List.Items[i];
mmo1.Lines.Add('Имя: ' + mess.name + ', Тема: ' + mess.tema);
end;
finally
Dispose(mess);
end;
При таком варианте утечки памяти не будет?
Тимоха (2009-02-03 20:50:00) [26]Спасибо!
Т.е. в рабочем треде нужно создать property в него записывать данные
а при onterminate
в procedure HandleOnTerminate(Sender:TObject);
обращаться к потоку к заданному property и вытаскивать оттуда данные?
Медвежонок Пятачок (2009-02-03 20:46:00) [27]в онтерминате обработчике нитка еше жива.
и живы свойства нитки
Тимоха (2009-02-03 20:32:00) [28]Для OnTerminate:
делаю
...
procedure HandleOnTerminate(Sender:TObject);
...
MyThread:= TTest.create(' http://www.delphimaster.ru/cgi-bin/forum.pl?n=18');
MyThread.OnTerminate := HandleOnTerminate;
Не понимаю как будут передаваться данные в этом случае? Как поток отработает, наступает OnTerminate, тут то мы и должны данные где то хранить (в буфере?), вытаскиваем из буфера и все тип-топ. Так должен выглядеть алгоритм?
Сергей М. (2009-02-03 20:23:00) [29]Ясно)
Тимоха (2009-02-03 20:14:00) [30]Меня все устраивает, я хочу сделать оба варианта. И понять какой лучше.
Сергей М. (2009-02-03 20:12:00) [31]
> Тимоха (03.02.09 19:57) [86]
Что ты как попугай заладил одно и то же ?)
На [85] ответь)..
Тимоха (2009-02-03 19:57:00) [32]Это в execute рабочего треда:
repeat
New(mess); // выделяю память
count_name := PosEx('', page, index_name);
count_tema := PosEx('', page, index_tema);
mess.tema := Copy(page, index_tema + 7, count_tema - index_tema - 7);
mess.name := Copy(page, index_name + 9, count_name - index_name - 9);
SendMessage(hwnd, wm_buf, 0, Integer(mess));
index_name := PosEx('', page, count_name);
index_tema := PosEx('&n=18">', page, count_tema);
until index_name = 0;
Это в мэйнтреде:
try
mess := PRecord(message.LParam);
mmo1.lines.Add('Имя: ' + mess.name + ', Тема: ' + mess.tema);
finally
Dispose(mess); удаляю
end;
Сергей М. (2009-02-03 08:24:00) [33]И чем не устраивает вариант с обработкой OnTerminate ?
Сергей М. (2009-02-03 08:18:00) [34]
> что плохого в Self?
Ничего плохого.
Но ты же ведь не понимаешь, зачем тут этот Self, раз написал его ..
Какой смысл лезть в дебри, если нет понимания основ ?
> верно ли будет такая реализация с памятью?
>
Где, в каком месте кода все это происходит ?
Тимоха (2009-02-03 06:27:00) [35]Возникли вопросы по поводу памяти,
repeat
New(mess); // выделяю память
count_name := PosEx('', page, index_name);
count_tema := PosEx('', page, index_tema);
mess.tema := Copy(page, index_tema + 7, count_tema - index_tema - 7);
mess.name := Copy(page, index_name + 9, count_name - index_name - 9);
SendMessage(hwnd, wm_buf, 0, Integer(mess));
index_name := PosEx(' ', page, count_name);
index_tema := PosEx('&n=18">', page, count_tema);
until index_name = 0;
try
mess := PRecord(message.LParam);
mmo1.lines.Add('Имя: ' + mess.name + ', Тема: ' + mess.tema);
finally
Dispose(mess);удаляю
end;
верно ли будет такая реализация с памятью?
Тимоха (2009-02-03 05:25:00) [36]Передаю record через указатель.
try
mess := PRecord(message.LParam);
mmo1.lines.Add('Имя: ' + mess.name + ', Тема: ' + mess.tema);
finally
Dispose(mess);
end;
Результат:
Имя: koha!, Тема: Вопрос по функции API Openfile()
Имя: Тимоха, Тема: Организация работы потоков
Имя: mr.devil, Тема: Задание кодировки для xml
Имя: CodeMaster, Тема: Отключение скроллбаров
Имя: killaTank, Тема: Создание базы (Db) с помошью Delphi
Имя: cruiser, Тема: WinInet и закачка файла из Интернет через прокси с авторизацией.
Тимоха (2009-02-03 01:01:00) [37]вмысле без него))))))))
Тимоха (2009-02-03 00:58:00) [38]Спасибо! что плохого в Self?
Riply (2009-02-03 00:51:00) [39]> [73] Тимоха (02.02.09 23:37)
> Когда тогда надо задавать приоритет? и выставлять freeonterminate?
Да мне кажется, что Сергей М. в [71] инересовался присхождением Self. :)
P.S.
А ты молодец.
При прочтении данной ветки, складывается такое впечатление, что все у тебя получится.
(Рано или поздно :) )
Eraser (2009-02-03 00:22:00) [40]> [77] Тимоха (03.02.09 00:01)
можно, только после inherited.