Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Многопоточность.


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


Наверх

Титульная страница Поиск, карта сайта Написать письмо