Создание многопоточного приложения [Delphi]

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Artist, 4 Aug 2010.

  1. fenixelite

    fenixelite Banned

    Joined:
    7 Feb 2010
    Messages:
    294
    Likes Received:
    56
    Reputations:
    6
    FreeOnTerminate поставь true;
    Все нормально заканчивается....

    MyThread := TMyThread.Create(True);

    В Execute
    While (not terminated) do
    Form1.Memo1.Lines.Add('Working');

    И код уничтожения
    MyThread.Terminate;
     
  2. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Code:
    var
      thr: array [1..100] of TNew;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
    i:integer;
    begin
      for i:=1 to SpinEdit1.Value do
      begin
        TerminateThread(thr[i].Handle);
        thr[i].Free;
      end;
      SetLength(thr, 0);
    end;
    Решение "в лоб". Потоки гарантиоввнно убьются. Но если у тебя в теле потока будут не освобожденные ресурсы - словишь утечку памяти.
     
  3. Artist

    Artist Member

    Joined:
    10 Jul 2010
    Messages:
    89
    Likes Received:
    5
    Reputations:
    0
    Есть программа которая копирует с Memo2 в Memo1 n-ое количество строк, пока Memo2.lines.Count=0 .
    Вот что получилось:

    Code:
    procedure TNewThread.Int;
    begin
    s:=copy(Form1.Memo2.Lines[0],1,15);
    Form1.Memo2.Lines.Delete(0);
    end;
    
    procedure TNewThread.Out;
    begin
    Form1.Memo1.Lines.Add(s);
    end;
    
    
    procedure TNewThread.Execute;
    begin
    while not Terminated do
    begin
    Synchronize(Int);
    Synchronize(Out);
    if Form1.Memo2.Lines.Count=0 then
    begin
    Terminate;
    end;
    end;
    end;
    
    При запуске в 1 поток он копирует на 1 символ больше.
    При запуске в 2 потока он копирует на 2 символ больше.
    и так далее.
    То есть когда Memo2.Lines.Count=0 он завершает все потоки, но они проходят цикл еще по 1 разу и только после этого завершаются.
    Как это исправить?
    Вот сама программа+исходники TThread
    Будет очень полезна для тех кто только начинает изучать потоки!
     
  4. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    if Form1.Memo2.Lines.Count=0 then
    Это надо делать в синхронизации, посмотри мой предыдущий пример
     
  5. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    утечку памяти ты и так словиш потому что система не освобождает память из под стеков потоков прибитых через TerminateThread
     
  6. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Ты прав, но не совсем - стек освободится, а вот все что выделено в куче нет. Но в любом случае это решение для крайних ситуаций
     
  7. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    Windows via C/C++
     
  8. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    http://msdn.microsoft.com/en-us/library/ms686717(VS.85).aspx
     
  9. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Прошу прощения, протупил. Вы правы, стек не освободится.
     
  10. Artist

    Artist Member

    Joined:
    10 Jul 2010
    Messages:
    89
    Likes Received:
    5
    Reputations:
    0
    При работе с большим количеством строк в несколько потоков возникает проблема:
    Форма программы зависает, но сама программа работает.
    Как это исправить?
     
  11. BrainDeaD

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

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    форму в отдельный поток.
     
  12. Artist

    Artist Member

    Joined:
    10 Jul 2010
    Messages:
    89
    Likes Received:
    5
    Reputations:
    0
    И как форму сделать в отдельном потоке?Я даже это себе не представляю.
     
  13. aydar

    aydar Member

    Joined:
    12 Nov 2009
    Messages:
    259
    Likes Received:
    6
    Reputations:
    -2
  14. Redeemer

    Redeemer Member

    Joined:
    3 Jul 2010
    Messages:
    203
    Likes Received:
    24
    Reputations:
    1
    Она и так в отдельном потоке у него

    Вообще не в тему.

    В данной ситуации все проще и трагичнее. Все вызовы Synchronize выполняются в контексте основного потока. У тебя слишком много и слишком часто вызываются синхронизации, поэтому поток просто "забивается" этими вызовами.
    Выхода здесь два:
    1. Вставь в потоке перед вызовом синхронизаций Sleep(Random(20)), это разгрузит основной поток, но снизит производительность.
    2. просто забей. В реальном приложении, когда синхронизации будут вызываться не так часто, этот эфеект не проявится.