powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Корректное завершение потока
25 сообщений из 51, страница 2 из 3
Корректное завершение потока
    #39478014
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0r,

StealthForm почему не использовать например TObjectList<> с OwnerData для хранения списков потоков?
поток должен проверять Terminated при своей работе и выходить в случае его установки - его устанавливает вызов Terminate из деструктора что ИМХО неправильно


_Vasilisk_ , некультурно использовать системное апи в таких примитивных вещах
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478033
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)некультурно использовать системное апи в таких примитивных вещахГораздо культурнее городить десяток классов-обвязок
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478053
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_kealon(Ruslan)некультурно использовать системное апи в таких примитивных вещахГораздо культурнее городить десяток классов-обвязок
не думаю что у ТС тот случай, когда обвязки приходится использовать
согласен, что архитектурно там нашкодили прилично, но в целом на простых вещах довольно юзабельно
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478469
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТС в итоге решил не усложнять себе жизнь.
Вырубил\переделал все, что при завершении могло что-то слать или запрашивать у главного потока. В итоге теперь хватает простого
Код: pascal
1.
Result := WaitForSingleObject(Handle, 10000) <> WAIT_TIMEOUT


потратил время, но так намного лучше, чем извращения с зацикливаниями thread <-> main thread
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478498
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rТС в итоге решил не усложнять себе жизнь.
Вырубил\переделал все, что при завершении могло что-то слать или запрашивать у главного потока. В итоге теперь хватает простого
Код: pascal
1.
Result := WaitForSingleObject(Handle, 10000) <> WAIT_TIMEOUT


потратил время, но так намного лучше, чем извращения с зацикливаниями thread <-> main thread
Я знаю толк в извращениях, но
чем помешала стандартная защита от дедлока, непонятно

почему не использовать стандартный деструктор потока вместо API, тоже непонятно
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478531
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)потратил время, но так намного лучше, чем извращения с зацикливаниями thread <-> main thread
Я знаю толк в извращениях, но
чем помешала стандартная защита от дедлока, непонятно

почему не использовать стандартный деструктор потока вместо API, тоже непонятно


1) тем, что лучше предотвратить возможность дедлока, чем бороться с последствиями. Это, впрочем, не только дедлока касается.
2) тем, что мы с тобой говорим о разных вещах видимо.
У меня:
- поток с FreeOnTerminate = False;
- в Stop_MainThread я даю ему сигнал закончить все работы и завершить метод Execute
- дальше TThread делает EndThread потоку, и срабатывает моё WaitForSingleObject(Handle, 10000)
- если Stop_MainThread возвращает True - то значит поток успешно завершился, можно освобождать его (и все, что в нем). Если False - значит поток еще чего-то там доделывает, освободить его в этот момент - это гарантированно получить вагон ошибок. Пропускаем, идем к следующему.

а что ты понимаешь под "использовать стандартный деструктор" - я так и не понял :)
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478566
Фотография krapotkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
там вообще в принципе все без бубнов призвано работать
можно даже вообще без апи и WaitForMultipleObjects...
достаточно например при завершении в OnTerminate доложить, что завершен, в главный поток.
и когда все потоки закончили работу, продолжить выход из программы
никаких проблем никогда не возникало с этим подходом.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478568
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rПропускаем, идем к следующему.Почему бы все это не сделать так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
var
  H: array of THandle;
begin
  ВсемЗавершиться;
  for th in Threads do
    H.Add(th.Handle);
  while H.Count > 0 do begin
    Res := WaitForMultipleObjects(H.Count, @H[0], False, INFINITE);
    Win32Check(Res <> WAIT_FAILED);
    Threads[Res].Free;
    Threads.Delete(Res);
    H.Delete(Res);
  end;
end;

Все в псевдокоде, но думаю, что идея ясна. Тогда не нужно никого ждать и опрашивать. Кто первый завершился того и убиваем
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478573
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krapotkinи когда все потоки закончили работу, продолжить выход из программыЕсли вызов деструктора потока (объекта класса TThread) - тяжелая операция, то имеет смысл его вызывать по мере завершения потоков

Сам, всегда использую FreeOnTerminate + событие с ручным сбросом, чтобы уведомить все потоки сразу о завершении + инверсный семафор, чтобы знать когда все закончилось
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478580
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0r, идем к следующему , а можно и сразу пачкой WaitForMultipleObjects, и да, пропускаем , если дальше ExitProcess.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478586
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Vizit0rПропускаем, идем к следующему.Почему бы все это не сделать так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
var
  H: array of THandle;
begin
  ВсемЗавершиться;
  for th in Threads do
    H.Add(th.Handle);
  while H.Count > 0 do begin
    Res := WaitForMultipleObjects(H.Count, @H[0], False, INFINITE);
    Win32Check(Res <> WAIT_FAILED);
    Threads[Res].Free;
    Threads.Delete(Res);
    H.Delete(Res);
  end;
end;

Все в псевдокоде, но думаю, что идея ясна. Тогда не нужно никого ждать и опрашивать. Кто первый завершился того и убиваем

_Vasilisk_Почему бы все это не сделать так
несколько причин навскидку
1) не было уверенности в гарантированной окончании работы потока в разумные сроки. Но сейчас я вроде по всем таким "тяжелым" местам прошелся.
2) NextGen не умеет в WaitForMultipleObjects.

но так побыстрее должно прибиваться все это хозяйство. Всуну его наверное с IFDEF под винду.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478601
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rне было уверенности в гарантированной окончании работы потока в разумные срокиЭто ахтунг! Но костыль можно предложить такой

Код: pascal
1.
2.
3.
4.
5.
6.
7.
Res := WaitForMultipleObjects(H.Count, @H[0], False, 10000);
case Res of
  WAIT_FAILED: RaiseLastOsError;
  WAIT_TIMEOT: ВсеРаботаютНадоЧтоТоДелать;
else
  Прибить(Res);
end;


Vizit0r2) NextGen не умеет в WaitForMultipleObjects.Это аргумент. Нужно посмотреть, может там есть что-то подобное
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478644
Basilisk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vizit0rв приложении есть треды (один, два, десять, хоть сто).
Пытаюсь их корректно останавливать.

В закрытии главного окна делаю

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
  while StealthForm.CharListBox.Items.Count > 0 do
  begin
    Char_Obj := TBaseCharacter(StealthForm.CharListBox.Items.Objects[0]);
    StealthForm.CharListBox.Items.Delete(0);

    if ValidObject(Char_Obj) then
      if Char_Obj.Stop_MainThread then
        Char_Obj.DisposeOf;
  end;




Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
function TBaseCharacter.Stop_MainThread : Boolean;
var H : THandle;
begin
  Char_Started := False;
  LegalDisposeChar := True;
  {$IFDEF HAS_FMX}
  //Result := Self.WaitFor = 0;
  Self.WaitFor;
  Result := True;
  {$ELSE}
  RemoveQueuedEvents(Self);
  if TThread.CurrentThread.ThreadID <> MainThreadID then
    Result := WaitForSingleObject(Handle, 10000) <> WAIT_TIMEOUT
  else
  begin
    H := Handle;
    while True do
      case MsgWaitForMultipleObjects(1,H, False, 10000, QS_ALLEVENTS) of
        WAIT_OBJECT_0 : Exit(True);
        WAIT_OBJECT_0 + 1 : if Assigned(ProcessMessagesProc) then ProcessMessagesProc;
        WAIT_TIMEOUT : Exit(False);
      end;
  end;
  {$ENDIF}
end;



Проблема тут - 10с проходит, WAIT_TIMEOUT не срабатывает. Не срабатывает он и потом.
В отладке же чудеса - если кидаю бряк на выход из процедуры - срабатывает таймаут нормально. Но чудес же не бывает.

Я что-то делаю не так?

Связывать выполнение/завершение отдельных потоков с частной формой (особенно с элементами типа List) - плохая идея. Не делай так.

- если Stop_MainThread возвращает True - то значит поток успешно завершился, можно освобождать его (и все, что в нем). Если False - значит поток еще чего-то там доделывает, освободить его в этот момент - это гарантированно получить вагон ошибок. Пропускаем, идем к следующему.

У меня рабочий день закончен. Мне как-то на твои потоки и их завершение совершенно насрать. Как и на твои ошибки.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478650
Basilisk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_Bred eFeMкогда поток сам делает своему хэндлу CloseHandle() то это, наверное, не очень правильно ?Почему? Что в этом не правильного? Есть класс TThread, который инкапсулирует работу с потоком. Этот класс в своем конструкторе создает поток и получает его хэндл. Будет вполне логично этот хэндл закрыть, когда у класса отпадет в нем необходимость. Что он и делает. Закрыти хэндла на работоспособность потока никак не влияет
Потому что когда хэнд закрыт, он закрыт.
На работоспособность потока это никак не влияет. Но вот на возможность управления потоком через скопированный (не дублированный) хэнд это влияет.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478652
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Завернул убивание ссылки на OnTerminate, гоняю под нагрузками - все быстро закрывается. ЧИТД. Всем спасибо.



BasiliskУ меня рабочий день закончен. Мне как-то на твои потоки и их завершение совершенно насрать. Как и на твои ошибки.

Ты пришел сюда специально, чтобы написать что тебе насрать на этот топик и мои проблемы?
Л - логика.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478658
Basilisk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BasiliskУ меня рабочий день закончен. Мне как-то на твои потоки и их завершение совершенно насрать. Как и на твои ошибки.
В этот моменте вынужденно поясню. Человек, который пользуется программой, он не в курсе, что нужно ждать чего-то. Ему проще компьютер выключить кнопкой.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478670
Basilisk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Vizit0rмои проблемы?

Твои проблемы это вот такой код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
  RemoveQueuedEvents(Self);
  if TThread.CurrentThread.ThreadID <> MainThreadID then
    Result := WaitForSingleObject(Handle, 10000) <> WAIT_TIMEOUT
  else
  begin
    H := Handle;
    while True do
      case MsgWaitForMultipleObjects(1,H, False, 10000, QS_ALLEVENTS) of
        WAIT_OBJECT_0 : Exit(True);
        WAIT_OBJECT_0 + 1 : if Assigned(ProcessMessagesProc) then ProcessMessagesProc;
        WAIT_TIMEOUT : Exit(False);
      end;
  end;
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478671
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тю блин. Тогда понятно.
Обычно дожидаются - это домашние (игровые) компы, там вобщем-то спешить некуда. 5-10 секунд это не критично.
Впрочем, сейчас побыстрее будет.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478673
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rkealon(Ruslan)потратил время, но так намного лучше, чем извращения с зацикливаниями thread <-> main thread
Я знаю толк в извращениях, но
чем помешала стандартная защита от дедлока, непонятно

почему не использовать стандартный деструктор потока вместо API, тоже непонятно


1) тем, что лучше предотвратить возможность дедлока, чем бороться с последствиями. Это, впрочем, не только дедлока касается.
2) тем, что мы с тобой говорим о разных вещах видимо.
У меня:
- поток с FreeOnTerminate = False;
- в Stop_MainThread я даю ему сигнал закончить все работы и завершить метод Execute
- дальше TThread делает EndThread потоку, и срабатывает моё WaitForSingleObject(Handle, 10000)
- если Stop_MainThread возвращает True - то значит поток успешно завершился, можно освобождать его (и все, что в нем). Если False - значит поток еще чего-то там доделывает, освободить его в этот момент - это гарантированно получить вагон ошибок. Пропускаем, идем к следующему.

а что ты понимаешь под "использовать стандартный деструктор" - я так и не понял :)
может с
поток с FreeOnTerminate = True;?
тогда бы ещё были понятны такие извраты, но даже в этом случае достаточно в OnTerminate убить ссылку на объект потока

стандартный деструктор потока вызывает Terminate и ждёт его завершения - нормальный код потока проверяет Terminated и завершается при установке этого флага, вот и непонятно с чего все эти танцы с бубнами
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478676
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
так уже.
при использовании уведомления OnTerminate уже нет смысла в лишних движениях для освобождения.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478747
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rпри использовании уведомления OnTerminate уже нет смысла в лишних движениях для освобождения
по моим наблюдениям, если у потока FreeOnTerminate = True, то при умирании потока "естественной смертью" ссылка на экземпляр потока не об- nil -яется. Попробуй сделать глобальную переменную и перед новым запуском потока проверить ее наличие
Код: pascal
1.
if Assigned(FConnectThread) then Exit;


Если освобождать память вручную через FreeAndNil ( + FreeOnTerminate = False), то память освобождается корректно.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478758
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как этоДокссылка на экземпляр потока не об- nil -яется.связано с этимДокFreeOnTerminate = False), то память освобождается корректно.?

Корректное освобождение памяти - это вызов деструктора. Точка. Кто и когда будет его вызывать - абсолютно фиолетово.

При вызове деструктора ссылка обнуляться не должна. Хотя бы потому, что этих ссылок может быть миллион. Но если тебе важно обнуление конкретной ссылки. то да - обнулять ее придется руками
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478762
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
конечно не обнуляется сам по себе указатель, с чего бы ему обнуляться.

Всё учтено.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478851
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Корректное освобождение памяти - это вызов деструктора. Точка. Кто и когда будет его вызывать - абсолютно фиолетово.
корректно - это когда каждый раз, как в первый раз. Нет? :)

Вот вы тут про хэндлы и другие умные слова. А практическая польза от всего этого словесного потока? Тогда уж в начале трэда уточняйте что ли, что значит корректно.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39478875
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доккорректно - это когда каждый раз, как в первый раз. Нет? :)это называется детерминированное поведение
...
Рейтинг: 0 / 0
25 сообщений из 51, страница 2 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Корректное завершение потока
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]