![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Многопоточность.
guru-ru © (2006-03-04 09:53:00)послушайте, как сделать многопоточность.
Чтобы был массив потоков.
В общем задача такая! Есть в базе более 100 URL адресов (программа проверяет установлена ли на них обратная ссылка, т.е. для обмена ссылками и поддержания их в актуальном состоянии) мне нужно реализовать многопоточность, чтобы проверка проходила в 10 потоков (или более, задается в спец.поле). я делаю так.
type
THttpThread = class(TThread)
protected
procedure Execute; override;
procedure ShowInfo;
procedure add;
public
URL:string;
end;
procedure ThttpThread.ShowInfo;
begin
//просто для информации сколько ща потоков работает
Form1.LineNow:=Form1.linenow+1;
form1.Caption:=inttostr(Form1.LineNow);
end;
procedure ThttpThread.add;
begin
//с лист бокс добавляем очередной проверенный урл
form1.Listbox2.Items.add(URL);
end;
procedure TForm1.ThreadTerminate(Sender: TObject);
begin
// вот так я уничтожаю потоки
Form1.LineNow:=Form1.linenow-1;
form1.Caption:=inttostr(Form1.LineNow);
(sender as Thttpthread).free;
//после уничтожения и записываю лист бокс в файл.
listbox2.Items.SaveToFile('link.txt');
end;
procedure ThttpThread.Execute;
begin
Synchronize(ShowInfo);
memo1:=Tstringlist.Create;
memo1.Clear;
http:=TidHTTP.Create(nil);
urls:=Тут я реализую выборку из бд урл
//отправляю запрос
memo1.Text := HTTP.Get(urls);
s1:='';
for x:=0 to memo1.Count-1 do
s1:=s1+memo1.Strings[x];
//и начинаю искать мою ссылку
while (length(s1)>0)and(pos('http://',s1)>0) do
begin
k:=pos('http://',s1);
ss:='';
while (s1[k]<>'"')and(s1[k]<>'<')and(s1[k]<>'>')and(s1[k]<>'''')and(s1[k]<>' ')and(s1[k]<>')')and(length(s1)>=k) do
begin
ss:=ss+s1[k];
inc(k)
end;
delete(s1,1,k);
if (pos('.gif',ss)<1)and(pos('.jpg',ss)<1)and(pos('.png',ss)<1)and(pos('.GIF',ss)<1 )and(pos('.JPG',ss)<1)and(pos('.PNG',ss)<1) then
begin
if моя ссылка then
begin
URL:=ss+':'+' ok';
synchronize(add);
end;
end;
end;
http.Free;
memo1.Free;
application.ProcessMessages;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
//создаю 10 потоков.
for t:=1 to 10 do
begin
httpThread[t] := ThttpThread.Create(false);
httpThread[t].OnTerminate:=ThreadTerminate;
end;
end;
httpThread[t]- массив потоков.
Но проблема в том, что он как-то слишком быстро отрабатывает, и есественно неправильно. Вот только почему????
подскажить плиз... может нужно сделать по другому?
Kolan (2006-03-04 13:45:00) [1]А я говорю, что когда он отработает ненадо спешить его удалять...
> мне же нужно после того как один
> > поток отработал, если в бд еще есть урл, запустить новый
Я имел в виду что зачем запускать новый если есть уже запушенный
Cybernik (2006-03-04 13:02:00) [2]Поток не может уничтожется не успев доработать если не вызвать руками его терминате.
Kolan (2006-03-04 12:40:00) [3]
> хорошо. TThread.FreeOnTerminate сделаю, а как узнать, когда
> поток закончил работать, мне же нужно после того как один
> поток отработал, если в бд еще есть урл, запустить новый,
> и так постоянно должны работать 10 потоков, пока в бд не
> кончатся урлы.
Зачем убивать и вновь запускать новвый поток. Просто когда поток окончил работу пусти заснет. А если работа есть и он спит, то просыпается и работает..
guru-ru (2006-03-04 10:45:00) [4]Спасибо, так рулит, но все равно не так как нужно. при сохранении не все данные в файл сохраняет. такое ощущение, что поток уничтожается, неуспев доработать. можно не memo1:=Tstringlist.Create нужно сохранять, а что-то другое, и не form1.Listbox2.Items.add(ss); делать. может он просто не успевает сохранять туда данные? или разные потоки данные перезаписывают там?
Dmitrij_K (2006-03-04 10:27:00) [5]Например что-то типа такого
THttpThread
...
public
Index:Integer;
...
end
Создание
for t:=1 to 10 do
begin
httpThread[t] := ThttpThread.Create(True);
httpThread[t].OnTerminate:=ThreadTerminate;
httpThread[t].Index := t;
httpThread[t].Resume
end;
Завершение
procedure TForm1.ThreadTerminate(Sender: TObject);
begin
...
k := (sender as Thttpthread).Index;
httpThread[k] := nil;
if Естm url then
begin
httpThread[k] := ThttpThread.Create(True);
httpThread[k].OnTerminate:=ThreadTerminate;
httpThread[k].Index := t;
httpThread[k].Resume
end
else ShowMessage('Конец')
end;
guru-ru (2006-03-04 10:12:00) [6]хорошо. TThread.FreeOnTerminate сделаю, а как узнать, когда поток закончил работать, мне же нужно после того как один поток отработал, если в бд еще есть урл, запустить новый, и так постоянно должны работать 10 потоков, пока в бд не кончатся урлы.
Dmitrij_K (2006-03-04 10:06:00) [7]1. Нельзя уничтожать класс в его же событии
procedure TForm1.ThreadTerminate(Sender: TObject);
...
(sender as Thttpthread).free;
Есть такая штука TThread.FreeOnTerminate
2.application.ProcessMessages;
В контексте потока это бесполезноделать
3. Я бы сделал еще так
...
try
memo1.Text := HTTP.Get(urls);
...
Finally
http.free;
...
end