![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проверка прокси серверов в потоках [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 должно быть защищено КС