Форум: "Начинающим";
Текущий архив: 2010.11.28;
Скачать: [xml.tar.bz2];
ВнизПроверка прокси серверов в потоках Найти похожие ветки
← →
HF-Trade © (2010-09-10 16:32) [0]Сразу скажу, с потоками практически не работал. =)
(Вопросы в самом низу)
Код -
В программе -
....
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 16:37) [1]
> ткните плс где ошибки
Первая же очевидная:
P := Mhttp[I].ProxyParams.ProxyServer + " " + PResult;
Обращение к P должно быть защищено КС
← →
HF-Trade © (2010-09-10 16:46) [2]Почему?
P - локальная переменная потока
← →
Сергей М. © (2010-09-10 16:48) [3]
> P - локальная переменная потока
Врешь)
Вот список локальных переменных потока:
> Procedure TProxyTest.Execute;
> Var
> I: Integer;
> PResult: String;
> begin
>
Ну и где здесь P ?
← →
HF-Trade © (2010-09-10 16:50) [4]) исправил -
блок финалли, заключил в КС
← →
HF-Trade © (2010-09-10 16:59) [5]Finally
Mhttp[I].Free;
Section.Enter;
P := Mhttp[I].ProxyParams.ProxyServer + " " + PResult;
ACountThread := ACountThread - 1;
Section.Leave;
Synchronize(AddMemo);
end;
Вот таким образом переделал...
Теперь в мемо ничего не попадает, цп грузит на 50% и в диспетчере висят 7 потоков...(
← →
Медвежонок Пятачок © (2010-09-10 17:02) [6]в коде все еще мало энтропии. надо больше.
← →
Сергей М. © (2010-09-10 17:10) [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;
← →
HF-Trade © (2010-09-10 17:34) [8]А разве созданный поток, не увеличивает ACountThread ?
Там же при создании -
I := vthrnum;
Section.Enter;
Inc(ACountThread);//<<
Inc(ACreateThread);
Section.Leave;
← →
Сергей М. © (2010-09-10 17:46) [9]Первый доп.поток сделает ACreateThread равным 1.
Проделав (быстро или медленно - не важно) свою грязную работу он вновь сделает ACreateThread равным 0 и "повиснет" до второго пришествия на Synchronize(AddMemo), потому что в этот момент основной поток создав в цикле первый (и пока еще единственный) доп.поток "завис" до второго пришествия на ожидании пока ACreateThread не станет больше или равно единице. А это условие никогда не станет истинным.
← →
Сергей М. © (2010-09-10 17:49) [10]
> (быстро или медленно - не важно)
Вообще-то вру, важно.
Быстренько обломавшись на исключении доп.поток сделал ACreateThread равным 0 и повис на Synchronize(AddMemo).
В этот момент осн.поток прочухался и дошел до проверки ACreateThread < vthrnum, что эквивалентно 0 < 1 = True
← →
HF-Trade © (2010-09-10 18:19) [11]ACreateThread, не обнуляется. - т.е. проделав работу поток не обнуляет эту перменную, он обнуляет Каунт - счетчик потоков. АКреатеФрид, нужен чтобы понять, что поток создан и ему присвоен правильный vhrnum, для работы с нужным индексом IdHTTP.
в приложении -
Inc(vthrnum);
потом ждем пока поток, получит индекс -
While ACreateThread < vthrnum do
Delay(100);
Поток создается, получает индекс
I := vthrnum;
и увеличивает счетчикИ
Section.Enter;
Inc(ACountThread);
Inc(ACreateThread);
...
в финалли, поток уменьшает значение только счетчика
ACountThread := ACountThread - 1;
Но не ACreateThread...
← →
HF-Trade © (2010-09-10 18:26) [12]Ну вот нашел ошибочку
I := vthrnum;
надо
I := vthrnum - 1;
С 0 индексом теперь понятно почему его не было).
...
← →
Сергей М. © (2010-09-10 20:53) [13]
> АКреатеФрид, нужен чтобы понять
Чтобы ПОНЯТЬ нужны не извращения со всякими "АКреатеФрид", а отладчик)
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.11.28;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.017 c