Delphi - помогите разобраться с синхронизацией потоков

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Drul, 10 Jul 2011.

  1. Drul

    Drul Banned

    Joined:
    15 May 2011
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Всем доброго времени суток.

    Не удалось найти программиста в разделах о работе - все заняты.

    Поэтому разбираюсь со всем сам с помощью статей. Что-то получается, а что-то нет.

    Требуется ваша помощь, чтобы разобраться с много поточностью и синхронизацией в Delphi

    Code:
    procedure TNewThread.Execute;
    var
      CurAcc: Integer;
      FAcc, FPas: string;
    begin
      Form1.Gauge1.MaxValue := data.Count;
      Form1.Button2.Enabled := False;
      Form1.Button3.Enabled := False;
      for CurAcc := 0 to data.Count - 1 do
      begin
        [COLOR=Red][B]Synchronize(CheckAccount);[/B][/COLOR]
        FAcc := Copy(data[CurAcc], 1, Pos(':', data[CurAcc]) - 1);
        FPas := Copy(data[CurAcc], Pos(':', data[CurAcc]) + 1, Length(data[CurAcc])
          );
        log('Чекаем аккаунт ' + FAcc + ':' + FPas);
        CheckAccount(FAcc, FPas);
        log('Закончили чекать аккаунт');
        Form1.Gauge1.Progress := CurAcc + 1;
      end;
      log('Работа завершена.');
      Form1.Button2.Enabled := true;
      Form1.Button3.Enabled := true;
    end;
    
    Code:
    procedure TForm1.Button3Click(Sender: TObject);
    const MAX_THREAD=2000;
    var
    thread:array[0..MAX_thread] of TNewThread;
    i:integer;
    begin
      if(Pos('0.0000', Label2.Caption) <> 0) then
      begin
        ShowError('Неверный ключ антикаптчи');
        exit;
      end;
     for i:=1  to strtoint(Edit2.Text) do
     begin
      thread[i]:=TNewThread.Create(false);
      thread[i].FreeonTerminate := true;
      thread[i].data := Accounts;
    end;
    
    Все это дело компилируется и работает, но как вы уже заметили, синхронизация вообще походу отсутствует и как ее сделать я без понятия...
    Подскажите пожалуйста решение проблемы?
     
  2. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    Не понял, что тебе нужно сделать?
     
  3. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    Это
    Form1.Gauge1.MaxValue := data.Count;
    Form1.Button2.Enabled := False;
    Form1.Button3.Enabled := False;
    И это
    Form1.Button2.Enabled := true;
    Form1.Button3.Enabled := true;
    нужно делать только в Synchronize

    и процедуру CheckAccount приведи. посмотрим, что с ней сделать можно.
    Как я понимаю она занимает длительное время и вряд ли ее целяком нужно делать в Synchronize
     
  4. Drul

    Drul Banned

    Joined:
    15 May 2011
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Все потоки работают с одним (первым) аккаунтов, потом все переходят ко второму.
    Как выполнить синхронизацию? Чтобы каждый новый поток использовал следующий аккаунт
     
  5. bad_boy

    bad_boy Elder - Старейшина

    Joined:
    30 Dec 2004
    Messages:
    187
    Likes Received:
    33
    Reputations:
    3
    Drul,
    Synchronize это, вероятно, не то, о чём ты подумал.
    Функция CheckAccount использует внутри себя VCL компоненты, для работы в потоке необходимо, чтобы эту функция фызывалась методом Synchronize.
    Нужно добавить классу TNewThread что-то вроде
    var Account : string;
    И потом:
    Code:
    thread[i]:=TNewThread.Create(true); //true значит CreateSuspended, т.е. поток не запускается сразу, после создания
      thread[i].FreeonTerminate := true;
      thread[i].Account := Accounts[i]; //сообщаем потоку, с каким аккаунтом он будет работать
      threads[i].Execute(); //а вот тту поток запускается
    
     
  6. NekitoSP

    NekitoSP New Member

    Joined:
    14 May 2010
    Messages:
    17
    Likes Received:
    0
    Reputations:
    0
    bad_boy,

    c каких это пор?) а тебе не кажется, что эта самая execute будет выполнена в основном потоке?) вообще-то threads.Resume запускает именно поток...
     
  7. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    NekitoSP не путай человека.
    Thread.Execute - это тело потока. Execute выполняется в потоке.
     
  8. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    937
    Likes Received:
    162
    Reputations:
    27
    ТС, насчет синхронизации прочитайте про критические секции. Инфу можете найти в поисковике.
     
  9. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    На винграде есть классная статейка по поводу работы с потоками (мне она очень помогла):
    http://forum.vingrad.ru/index.php?showtopic=60076&view=findpost&p=480303

    всем рекомендую, но никто почему-то не читает.
    Там отлично рассматриваются все проблемы связанные с использованием потоков и синхронизация
     
  10. Drul

    Drul Banned

    Joined:
    15 May 2011
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Вроде бы это путь к истине, но не понимаю, как это использовать...


    Я это тоже находил и частями читал, но сложно все это понять :(


    Спасибо, посмотрю. Уже сталкивался...
     
    #10 Drul, 10 Jul 2011
    Last edited: 10 Jul 2011