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

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

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

Восстановить пароль

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

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

Цитата:
по завершению работы потока процедура проверки должна вывести "Поток "MyThread" работает"?
Нет не должна. Потому что нигде не вызывается из потока или в OnTerminate потока.
Проверка у данном коде посажена на... кнопку походу, и к потоку отношение имеет косвенное.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.10.2013, 12:49   #22
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

Но в этом примере, если поток прервать, то при проверке показывается, Поток "MyThread2" не работает. Чего не хватает потоку при автоматическом завершении, чтобы было такое же состояние: "Поток "MyThread2" не работает"?
Код:
type
  TMyThread2 = class(TThread)
  private
    { Private declarations }
    i: Integer;
  protected
    procedure Execute; override;
    procedure DoTerminate; override;
    procedure SyncProc;
  public
  end;

var
  FormMain: TFormMain;
  MyThread2: TMyThread2;

implementation

{$R *.dfm}

procedure TFormMain.BStart2Click(Sender: TObject);
var
  ThreadDieCode: Integer;
begin
  if BStart2.Tag = 0 then
  begin
    BStart2.Tag := 1;
    BStart2.Caption := 'Стоп';

    MyThread2 := TMyThread2.Create(True); // После создания поток остановлен
    MyThread2.FreeOnTerminate := False; // После завершения работы поток "не умрёт" сам
    MyThread2.Resume; // Запуск потока
  end
  else
  begin
    BStart2.Tag := 0;
    BStart2.Caption := 'Старт';
    // Поток не прекращает свою работу
    // НЕ УБИВАЕТ поток, а просто выставляет свойство Terminated в True
    // Поток сам должен следить (в теле Execute) за тем, когда должен умереть
    // Жёстко уничтожить поток можно с помощью TerminateThread, но делать этого нельзя, потому как утечки памяти как минимум... ну и прочие неприятности
    MyThread2.Terminate;
    // Если нужно дождаться когда MyThread2 "мирно" помрёт (например после вызова MyThread2.Terminate;)
    ThreadDieCode := MyThread2.WaitFor;
    // А ещё не забываем высвобождать память
    MyThread2.Free;
  end;
end;

procedure TMyThread2.Execute;
var
  i2: Integer;
begin
  for i2 := 0 to 60 do
  begin
    if i2 > 61 then Break;
    Sleep(100);
    i := i2;
    Synchronize(SyncProc);

    if Self.Terminated then Break; // Если главный поток приказал - умираем
  end;
end;

procedure TMyThread2.SyncProc;
begin
  FormMain.Caption := IntToStr(i);
end;

procedure TMyThread2.DoTerminate;
begin
  // Что-то... Если нужно до вызова внешнего OnTerminate (если назначен)
  inherited;
  // Что-то... Если нужно после вызова внешнего OnTerminate (если назначен)
end;

procedure TFormMain.BCheck2Click(Sender: TObject);
begin
  // Проверка на существование потока
  if MyThread2 <> nil then
  begin
    // Если поток умирает "мирно", штатно завершив работу
    if MyThread2.Terminated then ShowMessage('Поток "MyThread2" не работает') else ShowMessage('Поток "MyThread2" работает');
  end else ShowMessage('Поток "MyThread2" не создан');
end;
Shouldercannon вне форума Ответить с цитированием
Старый 05.10.2013, 13:27   #23
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
если поток прервать, то при проверке показывается, Поток "MyThread2" не работает.
Ключевое слово: то при проверке
Т.е. проверку ты потом запускаешь ручками.
А ты хочешь:
Цитата:
по завершению работы потока процедура проверки должна вывести "Поток "MyThread" работает"
Это должно достигаться путем помещения ShowMessage('Поток "MyThread2" завершен'); в OnTerminate или просто в конец процедуры потока.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.10.2013, 16:29   #24
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

Не правильно выразился. Я вижу, что поток завершил выполнять код. Далее я жму на кнопку проверки состояния потока. Если я прерываю поток, а потом жму на кнопку проверки, то получаю: Поток "MyThread2" не работает, а если нажимаю на кнопку проверки после того, как поток завершил выполнять код, то вижу Поток "MyThread2" работает. И тоже самое увижу спустя какое-то время.
Shouldercannon вне форума Ответить с цитированием
Старый 05.10.2013, 16:36   #25
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

В этом случае я бы описал некое поле потока Stopped, которому бы присваивал true по завершению Execute, и уже делал проверку на него.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 08.10.2013, 10:09   #26
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,543
По умолчанию

постле того как поток был остановлен, он завершается,
в соответствии с кодом
Цитата:
Код:
    ThreadDieCode := MyThread2.WaitFor;
    // А ещё не забываем высвобождать память
    MyThread2.Free;
мы освобождаем память занятую полями потока и теперь ее состояние становится непредсказуемым.
И мы пытаемся узнать состояние у несуществуещего объекта.
подробности и способы лечения
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Старый 10.10.2013, 05:29   #27
Shouldercannon
Участник клуба Подтвердите свой е-майл
 
Аватар для Shouldercannon
 
Регистрация: 26.01.2008
Сообщений: 1,899
По умолчанию

В данном случает Terminate выставляет значение True у Terminated? И можно ли так делать (выполнять Terminate в конце кода потока)?
Код:
procedure TMyThread.Execute;
var
  i2: Integer;
begin
  for i2 := 0 to 60 do
  begin
    if i2 > 61 then Break;
    Sleep(100);
    i := i2;
    Synchronize(SyncProc);
  end;
  
  Terminate;
end;
Shouldercannon вне форума Ответить с цитированием
Старый 10.10.2013, 10:10   #28
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,543
По умолчанию

Цитата:
И можно ли так делать (выполнять Terminate в конце кода потока)?
можно, конечно. но зачем это надо?
а можно и так
Код:
terminated:=true; // просто установить соотв. флаг.
и так я думаю будет нагляднее(человеку) для последующего(через пару месяцев) анализа кода.
программа — запись алгоритма на языке понятном транслятору
evg_m вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопросец по потокам stlcrash Общие вопросы Delphi 8 11.07.2016 19:36
При освобождении обьекта TThread, он вешает всю программу. При этом код Execute у TThread уж выполнился.. Человек_Борща Общие вопросы Delphi 23 30.11.2011 09:18
Вопрос по потокам Karamzda Общие вопросы C/C++ 1 17.11.2010 16:43
Вопрос по потокам mspavlyxa Помощь студентам 6 25.03.2010 23:46
Вопрос по потокам Eretic Общие вопросы по Java, Java SE, Kotlin 5 02.04.2009 00:17