powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Корректное завершение потока
51 сообщений из 51, показаны все 3 страниц
Корректное завершение потока
    #39476324
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 не срабатывает. Не срабатывает он и потом.
В отладке же чудеса - если кидаю бряк на выход из процедуры - срабатывает таймаут нормально. Но чудес же не бывает.

Я что-то делаю не так?
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476336
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to get extended information call GetLastError
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476351
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
error нет.
есть MsgWaitForMultipleObjects, который крутится себе в вечном цикле, сообщения оконные обрабатывает, все такое - но выходить не выходит, ни по таймауту, ни с ошибкой.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476355
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0r,

На АОПе еще кто-то играет?
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476369
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КвейдVizit0r,

На АОПе еще кто-то играет?


ты задаешь этот вопрос уже второй или третий раз.
Я не в курсе, я не играю ни там, ни вообще на каком-то шарде.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476415
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если сделать так?

Код: pascal
1.
2.
3.
4.
5.
6.
      case MsgWaitForMultipleObjects(1,H, False, 10000, QS_ALLEVENTS) of
        WAIT_OBJECT_0 : Exit(True);
        WAIT_OBJECT_0 + 1 : if Assigned(ProcessMessagesProc) then ProcessMessagesProc;
      else
        Exit(False);
      end;
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476416
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rWAIT_TIMEOUT не срабатываеЗначит срабатывает, что-то другое. Например, WAIT_FAILED, что приводит к бесконечному циклу. А сам WAIT_FAILED возникает из-за того, что был вызван деструктор потока, который закрыл хэндл, и Вы ломитесь по невалидному хендлу. Чтобы такого не происходило, нужн
1) Заблаговременно вызывать DuplicateHandle
2) Предусматривать ВСЕ возможные возвращаемые значения
Vizit0rВ отладке же чудеса - если кидаю бряк на выход из процедуры - срабатывает таймаут нормальноПотому что меняется тайминг и поток не успевает вызвать деструктор
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476831
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну деструктор не вызывается, потому что FreeOnTerminate = False, но ход мыслей я понял.

Кстати, а DuplicateHandle зачем?
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476832
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rКстати, а DuplicateHandle зачем?Чтобы, когда поток сделает своему хэндлу CloseHandle() у тебя осталась валидная копия
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476845
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
интересно.
Не знал, спасибо.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39476868
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_, когда поток сам делает своему хэндлу CloseHandle() то это, наверное, не очень правильно ?
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477018
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeMкогда поток сам делает своему хэндлу CloseHandle() то это, наверное, не очень правильно ?Почему? Что в этом не правильного? Есть класс TThread, который инкапсулирует работу с потоком. Этот класс в своем конструкторе создает поток и получает его хэндл. Будет вполне логично этот хэндл закрыть, когда у класса отпадет в нем необходимость. Что он и делает. Закрыти хэндла на работоспособность потока никак не влияет
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477020
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vizit0rинтересно.
Не знал, спасибо.Только не забудь сам вызвать CloseHandle() для полученной копии
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477042
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Только не забудь сам вызвать CloseHandle() для полученной копиивот-вот, а по сути, конструктор то у тебя вне потока получает этот Handle, значит, архитектурно правильно, его и закрыть вне потока.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477068
Vizit0r
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Vizit0rинтересно.
Не знал, спасибо.Только не забудь сам вызвать CloseHandle() для полученной копии

ну это само собой.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477186
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeMвот-вот, а по сути, конструктор то у тебя вне потока получает этот Handle, значит, архитектурно правильно, его и закрыть вне потока.Хэндл получается в конструкторе класса, закрывается в деструкторе класса. Что не так?
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477203
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_ Что не так?DuplicateHandle зачем?
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477337
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeM,

_Vasilisk_Vizit0rКстати, а DuplicateHandle зачем?Чтобы, когда поток ( читать - объект класса TThread ) сделает своему хэндлу CloseHandle() у тебя осталась валидная копия
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477386
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_когда поток (читать - объект класса TThread) сделает своему хэндлу CloseHandle() конструктор то у тебя вне потока получает этот Handle, значит, архитектурно правильно, его и закрыть вне потока Ситуация, когда в рамках одного процесса действительно нужна копия хэндла, мне непонятна.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477761
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bred eFeMконструктор то у тебя вне потока получает этот Handle, значит, архитектурно правильно, его и закрыть вне потока Опять по новому кругу. Ну открой ты исходники и посмотри TThread.Create, TThread.Destroy
Bred eFeMСитуация, когда в рамках одного процесса действительно нужна копия хэндла, мне непонятна.Хендлом владеет экземпляр класса TThread. Он его порождает, он же его и убивает. Если хэндл используется где-то вне этого объекта и существует вероятность обращения к этому хэндлу после уничтожения объекта, то нужно делать копию
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477786
Bred eFeM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_, как это хэндл используется где-то вне этого объекта после класс TThread, который инкапсулирует работу с потоком.
Ладно, CloseThread(Self); ))
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477844
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Bred eFeMпропущено...
Опять по новому кругу. Ну открой ты исходники и посмотри TThread.Create, TThread.Destroy
Bred eFeMСитуация, когда в рамках одного процесса действительно нужна копия хэндла, мне непонятна.Хендлом владеет экземпляр класса TThread. Он его порождает, он же его и убивает. Если хэндл используется где-то вне этого объекта и существует вероятность обращения к этому хэндлу после уничтожения объекта, то нужно делать копию

Я дико извиняюсь, но Handle - это сущность, которой владеет процесс, а не поток.
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477853
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schiЯ дико извиняюсь, но Handle - это сущность, которой владеет процесс, а не поток.И что?
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477873
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_schiЯ дико извиняюсь, но Handle - это сущность, которой владеет процесс, а не поток.И что?

Эта фраза "Хендлом владеет экземпляр класса TThread. Он его порождает, он же его и убивает. Если хэндл используется где-то вне этого объекта и существует вероятность обращения к этому хэндлу после уничтожения объекта, то нужно делать копию "
меня напрягла. Как только ты сделал DuplicateHandle, тебе надо его явно закрывать, причем всегда, иначе объект потока будет жить вечно. И зачем этот зомби нужен ?
...
Рейтинг: 0 / 0
Корректное завершение потока
    #39477898
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
schiКак только ты сделал DuplicateHandle, тебе надо его явно закрывать, причем всегда, иначе объект потока будет жить вечноА где я говорил другое?_Vasilisk_Только не забудь сам вызвать CloseHandle() для полученной копии
...
Рейтинг: 0 / 0
Корректное завершение потока
    #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
Корректное завершение потока
    #39478889
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)это называется детерминированное поведение
Ага, а пригляделась получше ... :)
...
Рейтинг: 0 / 0
51 сообщений из 51, показаны все 3 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Корректное завершение потока
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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