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

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

Проверка прокси серверов в потоках [D7, XP]


HF-Trade ©   (2010-09-10 16:32:00) 

Сразу скажу, с потоками практически не работал. =)
(Вопросы в самом низу)

Код -

В программе -

....

Var
MHttp: Array of TIdHttp;
vthrnum: Integer;
ACreateThread: Integer;
ACountThread: Integer;
Section: TCriticalSection;

....

procedure TForm1.FormCreate(Sender: TObject);
begin
Section := TCriticalSection.Create;
end;

Procedure Delay(ms : longint);
Var
TheTime : LongInt;
Begin
TheTime := GetTickCount + ms;
While GetTickCount < TheTime Do
 Application.ProcessMessages;
End;

procedure TForm1.Button1Click(Sender: TObject);
Var
I: Integer;
Begin
MHttp := nil;
SetLength(MHttp, LBServer.Items.Count);
VthrNum := 0;
ACountThread := 0;
ACreateThread := 0;
For I:=0 to LB.Items.Count - 1 do
 Begin
  MHttp[I] := TidHttp.Create(nil);
  Mhttp[I].ReadTimeout := 4000;
  Mhttp[I].ConnectTimeout := 4000;
  MHttp[I].AllowCookies := True;
  Mhttp[I].ProxyParams.ProxyPort := StrToInt(LBPort.Items[I]);
  Mhttp[I].ProxyParams.ProxyServer := LBServer.Items[I];
 end;
 vthrnum:=0;
 ACreateThread := 0;
 ACountThread := 0;
 For I := 0 to LB.Items.Count - 1 do
  begin
   TestProxy := TProxyTest.Create(True);
   TestProxy.FreeOnTerminate := True;
   TestProxy.Resume;
   Inc(vthrnum);
   While ACreateThread < vthrnum do
    Delay(100);
   While ACountThread > 4 do
    Delay(100);
  end;  

....

В потоке -

....

Var
P:String;

Procedure TProxyTest.AddMemo;
Begin
Form1.memo1.Lines.Add(P);
end;

Procedure TProxyTest.Execute;
Var
I: Integer;
PResult: String;
begin
I:=vthrnum;
Section.Enter;
Inc(ACountThread);
Inc(ACreateThread);
Section.Leave;
Try
 Try
  PResult := 'True';
  Mhttp[I].Get(' http://ya.ru');
 Except
  PResult := 'False';
 end;
Finally
  P := Mhttp[I].ProxyParams.ProxyServer + ' ' + PResult;
  Mhttp[I].Free;
  Section.Enter;
  ACountThread := ACountThread - 1;
  Section.Leave;
  Synchronize(AddMemo);
end;
end;

....

Ну и собсно вопросы -

1. Я вообще правильно делаю?=) Если нет, ткните плс где ошибки, что лучше делать по другому и т.п.

2. После запуска программы диспетчер показывает что созданы 2 потока,
а после отработки цикла, потоков остается 3. Откуда берется 3?

3. Почему(из-за чего) так медленно работает проверка?

4. После отработки цилка, в мемо не попадает информация о 0 элементе списка(самом верхнем),
почему?

Ну все, можно кидатся тапками=)


Сергей М.   (2010-09-10 20:53:00) [1]


> АКреатеФрид, нужен чтобы понять


Чтобы ПОНЯТЬ нужны не извращения со всякими "АКреатеФрид", а отладчик)


HF-Trade   (2010-09-10 18:26:00) [2]

Ну вот нашел ошибочку
I := vthrnum;
надо
I := vthrnum - 1;

С 0 индексом теперь понятно почему его не было).
...


HF-Trade   (2010-09-10 18:19:00) [3]

ACreateThread, не обнуляется. - т.е. проделав работу поток не обнуляет эту перменную, он обнуляет Каунт - счетчик потоков. АКреатеФрид, нужен чтобы понять, что поток создан и ему присвоен правильный vhrnum, для работы с нужным индексом IdHTTP.

в приложении -
Inc(vthrnum);
потом ждем пока поток, получит индекс -
While ACreateThread < vthrnum do
 Delay(100);

Поток создается, получает индекс
I := vthrnum;

и увеличивает счетчикИ
Section.Enter;
Inc(ACountThread);
Inc(ACreateThread);
...
в финалли, поток уменьшает значение только счетчика
 ACountThread := ACountThread - 1;
Но не ACreateThread...


Сергей М.   (2010-09-10 17:49:00) [4]


> (быстро или медленно - не важно)


Вообще-то вру, важно.
Быстренько обломавшись на исключении доп.поток сделал ACreateThread равным 0 и повис на Synchronize(AddMemo).
В этот момент осн.поток прочухался и дошел до проверки ACreateThread < vthrnum, что эквивалентно 0 < 1 = True


Сергей М.   (2010-09-10 17:46:00) [5]

Первый доп.поток сделает ACreateThread равным 1.
Проделав (быстро или медленно - не важно) свою грязную работу он вновь сделает ACreateThread равным 0 и "повиснет" до второго пришествия на Synchronize(AddMemo), потому что в этот момент основной поток создав в цикле первый (и пока еще единственный) доп.поток "завис" до второго пришествия на ожидании пока ACreateThread не станет больше или равно единице. А это условие никогда не станет истинным.


HF-Trade   (2010-09-10 17:34:00) [6]

А разве созданный поток, не увеличивает ACountThread ?
Там же при создании -

I := vthrnum;
Section.Enter;
 Inc(ACountThread);//<<
 Inc(ACreateThread);
Section.Leave;


Сергей М.   (2010-09-10 17:10:00) [7]

For I := 0 to LB.Items.Count - 1 do
 begin
  TestProxy := TProxyTest.Create(True);
  TestProxy.FreeOnTerminate := True;
  TestProxy.Resume;
  Inc(vthrnum);
// здесь ты "зависаешь" намертво при первом же проходе цикла
// потому что условие ACountThread < vthrnum всегда истинно
  While ACreateThread < vthrnum do
   Delay(100);
  While ACountThread > 4 do
   Delay(100);
 end;


Медвежонок Пятачок   (2010-09-10 17:02:00) [8]

в коде все еще мало энтропии. надо больше.


HF-Trade   (2010-09-10 16:59:00) [9]

Finally
  Mhttp[I].Free;
  Section.Enter;
  P := Mhttp[I].ProxyParams.ProxyServer + ' ' + PResult;
  ACountThread := ACountThread - 1;
  Section.Leave;
  Synchronize(AddMemo);
end;

Вот таким образом переделал...
Теперь в мемо ничего не попадает, цп грузит на 50% и в диспетчере висят 7 потоков...(


HF-Trade   (2010-09-10 16:50:00) [10]

) исправил -
блок финалли, заключил в КС


Сергей М.   (2010-09-10 16:48:00) [11]


> P - локальная переменная потока


Врешь)

Вот список локальных переменных потока:


> Procedure TProxyTest.Execute;
> Var
> I: Integer;
> PResult: String;
> begin
>


Ну и где здесь P ?


HF-Trade   (2010-09-10 16:46:00) [12]

Почему?
P - локальная переменная потока


Сергей М.   (2010-09-10 16:37:00) [13]


> ткните плс где ошибки


Первая же очевидная:

P := Mhttp[I].ProxyParams.ProxyServer + ' ' + PResult;

Обращение к P должно быть защищено КС


Наверх

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