Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Проверить поток на существование  (Прочитано 1115 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Shouldercannon
Постоялец

ru
Offline Offline

« : 13-09-2016 12:51 » 

Реализация
Код: (Delphi)
procedure TFormMain.BStartClick(Sender: TObject);
begin
  MyThread := TMyThread.Create(True); // После создания поток остановлен
  MyThread.FreeOnTerminate := True; // После завершения работы поток "умрёт" сам
  MyThread.Start; // Запуск потока
end;

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;

procedure TMyThread.SyncProc;
begin
  FormMain.Caption := IntToStr(I);
end;

procedure TFormMain.BCheckClick(Sender: TObject);
begin
  // Проверка на существование потока
  if MyThread <> nil then
  begin
    // Если поток умирает "мирно", штатно завершив работу
    if MyThread.Terminated then ShowMessage('Поток "MyThread" не работает') else ShowMessage('Поток "MyThread" работает');
  end else ShowMessage('Поток "MyThread" не создан');
end;
В Execute потока есть вызов Terminate; благодаря чему проверка проходит нормально (Поток "MyThread" не работает), но делать так не советуют. Как правильно реализовать задуманное?
Записан
..::SCRIBE::..
Помогающий

ua
Offline Offline
Пол: Мужской
не путайте банальность с ленью=)


« Ответ #1 : 13-09-2016 14:09 » 

По нормальному делают наоборот, внутри Execute проверяют на Terminated, а снаружи вызывают Terminate.
Вообще признак завершенности можно сделать где угодно, хоть через тот же Synchronize в конце поставить в True какое-то свойство формы и т.д.
« Последнее редактирование: 13-09-2016 14:27 от ..::SCRIBE::.. » Записан
zubr
Модератор

by
Offline Offline
Пол: Мужской

« Ответ #2 : 13-09-2016 22:16 » 

Читайте матчасть или смотрите исходники компонентов.
Вот исходный код метода Terminate класса TThread:
Код:
procedure TThread.Terminate;
begin
  FTerminated := True;
end;
То есть все что он делает - это устанавливает свойство Terminated в True.
К примеру, поток:
Код:
procedure TMyThread.Execute;
begin
   while True do
   begin
      Sleep(100);
   end;

  Terminate; // Не советуют так делать
end;
будет крутиться бесконечно до закрытия процесса.
Даже если вызвать Terminate вне потока - он все равно не завершится.
А вот код:
Код:
procedure TMyThread.Execute;
begin
   while not Terminated do
   begin
      Sleep(100);
   end;  
end;
При вызове Terminate возможно завершит поток, если в коде самого потока не происходит какая то длительная операция или он вообще по каким то причинам завис.
Чтобы убедиться, что поток завершен, есть в классе TThread метод WaitFor, но и его использовать я бы не рекомендовал, потому что процесс или поток его вызвавший, будет стоять в ожидании завершения потока, а если поток завис?
В данном случае лучше юзать штатные средства Windows - WaitForSingleObject
Код:
  MyThread.Terminate;
   if WaitForSingleObject(MyThread.Handle, 1000) <> WAIT_OBJECT_0 then //ждем секунду
   TerminateThread(MyThread.Handle, 0); //убиваем поток принудительно
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines