[delphi] Потоки, нагрузка на ЦП

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Bo0oM, 3 Jun 2012.

  1. Bo0oM

    Bo0oM Member

    Joined:
    26 Dec 2009
    Messages:
    2
    Likes Received:
    35
    Reputations:
    21
    Задача - проверять списки сайтов на определённую страницу, работает шустро, быстро, загрузка ЦП в районе 10%, но через несколько минут работы (списки сайтов большие) ЦП - 100%. Что делать, как поступить?

    Вступление, ну кому нужно...
    Code:
      TMyThread = class(TThread)
      private
        FOnDone: TNotifyEvent;
        Rez : Integer;
      protected
        procedure Execute; override;
        procedure SyncMe;
        procedure WorkEnd;
      public
        Pass: String;
        Site: string;
        IP: string;
        Port: Integer;
        constructor Create(CreateSuspended: Boolean);
        destructor Destroy; override;
        property OnDone: TNotifyEvent read FOnDone write FOnDone;
      end;    
    
    var
      Form1: TForm1;
      i:string; z:Byte;
      Sites:Tstringlist;
      t:integer;
      Work,check:boolean;
      GoodFile, GoodFile2, GoodFile3: textfile; 
    
    implementation
    
    {$R *.dfm}
    
    { TMyThread }
    
    constructor TMyThread.Create(CreateSuspended: Boolean);
    begin
      inherited Create(CreateSuspended);
      FreeOnTerminate := True;
    end;
                                                             
    destructor TMyThread.Destroy;
    begin
      inherited;
    end;
    Сам поток

    Code:
    procedure TMyThread.Execute;
    var
        HTTP: TIdHTTP;
        a:string;
    begin
         HTTP:=TIdHTTP.create;
         HTTP.HandleRedirects:=false;
    //code
         try
          a:=HTTP.Get('http://'+Site+'/stranica.php');
         except
         end;
         if Pos('key', a)<>0 then rez:=1
         else
         rez:=0;
    //code
         Synchronize(SyncMe);//Єръ фюыцэю сvЄ№) фтр ёшэър
         HTTP.Free;
         Synchronize(WorkEnd);
    end;
    Code:
    procedure TMyThread.SyncMe;
    begin
    case Rez of
     1:
     begin
          Append(GoodFile);
          Writeln(GoodFile,'site');
          Closefile(GoodFile);
     end;
    // 2:
    // 3:
    //etc...
    
    end;
    end;
    Code:
    procedure TMyThread.WorkEnd;
       begin
      if Assigned(FOnDone) then
      FOnDone(Self);
    end;
    Code:
    procedure TForm1.btn1Click(Sender: TObject);
    var
      m: TMyThread; b:integer;
    begin
      if Sites.Count<>0 then
      begin
      for b := 0 to Min(StrToIntDef(Edt3.Text, 0), Sites.Count - 1) do
      begin
      m := TMyThread.Create(True);
      m.Site:=Sites[0];
      Sites.Delete(0);
      m.OnDone := DoneWork;
      m.Resume;
      end;
      end;
    Code:
    procedure TForm1.DoneWork(Sender: TObject);
    var
      m: TMyThread;
    begin
      lbl6.Caption:=IntToStr(Sites.Count);//осталось
      if Sites.Count > 0 then
      begin
        m := TMyThread.Create(True);
        m.Site:=Sites[0];
        Sites.Delete(0);
        m.OnDone := DoneWork;
        m.Resume;
    end;
     
  2. ADR-007

    ADR-007 Member

    Joined:
    12 Jul 2010
    Messages:
    218
    Likes Received:
    9
    Reputations:
    0
    А как контролируеш количество потоков?
     
  3. Jingo Bo

    Jingo Bo Member

    Joined:
    25 Oct 2009
    Messages:
    368
    Likes Received:
    51
    Reputations:
    7
    В принципе код годный, работать будет. Подозреваю вводишь в Edit3 много очень потоков, при высокой скорости интернета и большом списке - скорее всего забивается очередь обработки SyncMe и WorkEnd(не ясно почему нельзя было в одну это все запихнуть, кстати очередь станет в два раза меньше), от этого главная форма будет дико лагать, и загрузка процессора будет естессна больше. Если хочешь, что бы не тормозило - SyncMe не вызывай через Synchronize, а вызывай прямо в потоке, но только оберни в критическую секцию. И еще
    Code:
    constructor TMyThread.Create(CreateSuspended: Boolean);
    begin
      inherited Create(CreateSuspended);
      FreeOnTerminate := True;
    end;
    Это бред, надо так:
    Code:
    constructor TMyThread.Create(CreateSuspended: Boolean);
    begin
      inherited Create(true);
      FreeOnTerminate := True;
      if not CreateSuspended then
        Resume;
    end;
    Ну а это вообще убрать:
    Code:
    destructor TMyThread.Destroy;
    begin
      inherited;
    end;