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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 22.02.2014, 21:39   #11
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Как их все завершить принудительно?
Опиши в потоке поле типа boolean.
В цикле тела потока проверяй ее на true. Если она false - выйти из цикла.
Далее просто каждому потоку передавай false, и жди пока тот выйдет. Потом следующему и так в цикле.

P.S. Можно еще использовать свойство Terminated (что кстати с примером описано в хелпе), но я с ней как-то не особо подружился, не знаю почему.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 22.02.2014, 22:03   #12
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Опиши в потоке поле типа boolean.
В цикле тела потока проверяй ее на true. Если она false - выйти из цикла.
Далее просто каждому потоку передавай false, и жди пока тот выйдет. Потом следующему и так в цикле.

P.S. Можно еще использовать свойство Terminated (что кстати с примером описано в хелпе), но я с ней как-то не особо подружился, не знаю почему.
Что то я вообще ничего сообразить не могу. Можно пример о том как передать в рабочие потоки false?

Цитата:
Сообщение от Stilet Посмотреть сообщение
P.S. Можно еще использовать свойство Terminated
Вот я его и использую, передаю в цикле потокам - terminate, в самих потоках проверяю его. В итоге потоки продолжают работать.

Есть подозрение, что я не правильно тераминирую потоки.

Код:
procedure TForm1.Button2Click(Sender: TObject);
  var i:Integer;
  ThreadArray: array [1..3] of Thr;
begin

  if button2.Tag = 0 then
  begin

    button2.Tag:=1;

    for i:=1 to High(ThreadArray) do
    begin
      ThreadArray[i]:=Thr.Create(true);
      ThreadArray[i].FreeOnTerminate:=true;
      ThreadArray[i].Resume;
      ThreadArray[i].Priority:=tpNormal;
    end;

  end
  else
  begin

    button2.Tag:=0;
    for i:=1 to High(ThreadArray) do ThreadArray[i].Terminate;

  end;

end;
Здесь нужно учитывать, что некоторые потоки могут быть уже завершены. Если для них вызвать terminate будет ошибка.

Последний раз редактировалось Stilet; 22.02.2014 в 23:11.
bilibian вне форума Ответить с цитированием
Старый 22.02.2014, 22:37   #13
bulldog5293
Форумчанин
 
Регистрация: 13.05.2010
Сообщений: 670
По умолчанию

Цитата:
terminate, в самих потоках проверяю его
Что то не наблюдаю где ты это проверяиш
bulldog5293 вне форума Ответить с цитированием
Старый 22.02.2014, 22:45   #14
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию

Цитата:
Сообщение от bulldog5293 Посмотреть сообщение
Что то не наблюдаю где ты это проверяиш
Код:
procedure Thr.Execute;
begin
 while not Terminated do
 begin
  try
     // код
  except on E : Exception do
  begin
    // исключение
  end;
  end;
 end;
end;
bilibian вне форума Ответить с цитированием
Старый 22.02.2014, 22:49   #15
bulldog5293
Форумчанин
 
Регистрация: 13.05.2010
Сообщений: 670
По умолчанию

Код:
procedure Thr.Execute;
begin
   while True do
     if ThreadArray.Teminated then break;
end;
код выполняет бесконечный цикл. Однако, при выполнении в основной программе оператора
Код:
   ThreadArray.Terminate;
цикл завершается, и поток прекращает свою работу.
bulldog5293 вне форума Ответить с цитированием
Старый 22.02.2014, 22:59   #16
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию

Цитата:
Сообщение от bulldog5293 Посмотреть сообщение
Код:
procedure Thr.Execute;
begin
   while True do
     if ThreadArray.Teminated then break;
end;
код выполняет бесконечный цикл. Однако, при выполнении в основной программе оператора
Код:
   ThreadArray.Terminate;
цикл завершается, и поток прекращает свою работу.
Суть в том, что потоков несколько.

Этот код покажет ошибку.
Код:
ThreadArray.Terminate;
так как он требует, чтобы я сделал так:
Код:
ThreadArray[i].Terminate;
Но таким способом потоки не останавливаются.

Тоже самое и с:
Код:
ThreadArray.Teminated
bilibian вне форума Ответить с цитированием
Старый 22.02.2014, 23:10   #17
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Все там останавливается. Вот пример:
Код:
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type

  { TForm1 }

  { tt }

  tt=class(TThread)
    public i:integer;
    private procedure upd;
    protected procedure execute; override;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var  tl:TThreadList;
  Form1: TForm1;

implementation

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);

begin
 tl:=TThreadList.Create;


end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Button2.Click;
  tl.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var i:integer;  l:TList;
begin
 l:=tl.LockList;
 for i:=0 to l.Count-1 do begin
  with tt(l[i]) do begin
   Terminate;
   WaitFor;
  end;
 end;
 tl.UnlockList;
end;

procedure TForm1.Button1Click(Sender: TObject);
var i:integer; t:tt;
begin
 for i:=0 to 5 do begin
  ListBox1.Items.Append(IntToStr(i));
  t:=tt.Create(true);
  t.i:=i;
  tl.Add(t);
  t.Start;
 end;
end;

{$R *.lfm}

{ tt }

procedure tt.upd;
begin
 Form1.ListBox1.Items[i]:=TimeToStr(now);
end;

procedure tt.execute;
begin
  while not Terminated do begin
   Synchronize(@upd);
   Sleep(100);
  end;
  Form1.ListBox1.Items[i]:='Stoped';

end;

end.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.02.2014, 09:06   #18
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию

Stilet, спасибо!

Сделал так:

Код:
type
  Thr = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

var
  Form1: TForm1;
  tl:TThreadList;


procedure TForm1.Button2Click(Sender: TObject);
  var i:Integer;
  ThreadArray: array of Thr;
  l:TList;
begin
  if button2.Tag = 0 then
  begin

    tl:=TThreadList.Create;

    button2.Tag:=1;

    for i:=1 to High(ThreadArray) do
    begin

      ThreadArray[i]:=Thr.Create(true);
      ThreadArray[i].FreeOnTerminate:=false;
      ThreadArray[i].OnTerminate := ENDTerminated;
      tl.Add(ThreadArray[i]);
      ThreadArray[i].Resume;
      ThreadArray[i].Priority:=tpNormal;

    end;
  end
  else
  begin
    button2.Tag:=0;

    l:=tl.LockList;
    for i:=0 to l.Count-1 do begin
    with Thr(l[i]) do begin
      Terminate;
      WaitFor;
      Free;
    end;
    end;
    tl.UnlockList;
    tl.Free;
  end;
end;

Последний раз редактировалось bilibian; 23.02.2014 в 11:34.
bilibian вне форума Ответить с цитированием
Старый 23.02.2014, 16:57   #19
bilibian
Форумчанин
 
Регистрация: 21.01.2014
Сообщений: 389
По умолчанию

При запуске потоков я устанавливаю FreeOnTerminate:=false; так как если поставить True, то при остановке по кнопке будет ошибка "Thread Error: Неверный дескриптор (6)".

Так вот, при использовании FreeOnTerminate:=True; память освобождается по завершению работы потока, а если я использую FreeOnTerminate:=false; то как в этом случае быть?
bilibian вне форума Ответить с цитированием
Старый 23.02.2014, 17:46   #20
bulldog5293
Форумчанин
 
Регистрация: 13.05.2010
Сообщений: 670
По умолчанию

завести обработчик onterminated и внём убивать, +можно на форме сообщать что такой то поток убит или что ни будь другое
bulldog5293 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание нескольких потоков iKarma Общие вопросы Delphi 9 20.10.2011 18:11
Запуск нескольких потоков bulldog5293 Общие вопросы Delphi 3 11.11.2010 18:24
Как реализовать запуск и контроль нескольких однотипных потоков. Son Общие вопросы Delphi 5 29.04.2010 08:40
Работа с файлом из нескольких потоков boris-blade Общие вопросы .NET 2 02.04.2010 17:21
Запуск потоков в цикле VALERO Общие вопросы Delphi 11 01.03.2009 14:57