powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / как корректно убить поток?
35 сообщений из 35, показаны все 2 страниц
как корректно убить поток?
    #40008638
FIL23
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрых суток,

Предположим создаю поток с бесконечным циклом.

Код: 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.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
   TMyThreadCheckTasks = class(TThread)
     private
     { Private declarations }
   protected
     procedure Execute; override;
   end;

...

    procedure startMyThreadCheckTasks();
    procedure stopMyThreadCheckTasks();

//******************************************************************************
//стартуем поток проверки тасок
//******************************************************************************
procedure TForm2.startMyThreadCheckTasks();
begin
MyThreadCheckTasks:=TMyThreadCheckTasks.Create(false);                          //вначале нужно создать экземпляра потока .. параметр false запускает поток сразу после создания  true запуск впоследствии методом resume
MyThreadCheckTasks.Priority:=tpNormal;
MyThreadCheckTasks.FreeOnTerminate:=true;  //сам очистит память когда удалят
end;
//******************************************************************************
//******************************************************************************
//******************************************************************************
//остановка  потока
//******************************************************************************
procedure TForm2.stopMyThreadCheckTasks;                                    //останавливаем поток
begin
MyThreadCheckTasks.Terminate;
end;
//******************************************************************************
//******************************************************************************
//******************************************************************************
// поток 
//******************************************************************************
procedure TMyThreadCheckTasks.Execute();
var
   i:integer
begin
while not MyThreadCheckTasks.Terminated do
    begin
    inc(i)
    end;

end;
//******************************************************************************
//******************************************************************************




И все хорошо пока он вызывается один раз. А вот если их уже два или три. То при вызове stopMyThreadCheckTasks произойдет что то не понятное. А надо чтобы вырубился определенный поток.

Как отследить каждый поток отдельно и как вырубить определенный поток?

Я так подозреваю надо где то брать Handle и через него убивать.

Подскажите как корректно и как надо.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008644
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23> MyThreadCheckTasks:=TMyThreadCheckTasks.Create(false);
FIL23> procedure TMyThreadCheckTasks.Execute();
FIL23> while not MyThreadCheckTasks.Terminated do
FIL23> ...
FIL23> И все хорошо пока он вызывается один раз.
FIL23> А вот если их уже два или три.

Так это не про потоки вопросов, а про культуру
использования переменных. Вот потоков у Вас
два или три, а переменных?

FIL23> То при вызове stopMyThreadCheckTasks произойдет что то не понятное.

Ну почему же непонятное?... Это как раз вопрос
на знание азов (почти на собес) - что произойдёт
(эффектов будет несколько, более одного) ?


FIL23> Как отследить каждый поток отдельно и как вырубить определенный поток?

В простейшем случае - хранить ссылки на потоки
в каком-то контейнере (а-ля TList<TThtread>) и
соответственно у нужного вызывать Terminate c
обнулением ссылки на него.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008648
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
FIL23,

общего "корректного" метода нет.
Если ты имеешь права убить нить, то можешь вызвать TerminateThread (хэндл), но - нельзя сказать, что это корректно. Система остановит выполнение, немножко почистит память (кажись, только стек нити) но останется куча мусора (критические секции, выделенная память в куче, ... ) - они запросто накроются накроются медным тазом.
Нить должна завершаться сама, либо после завершения своей работы, либо по получению сигнала о необходимости завершиться.

Найди книжку "Рихтер Дж. - Windows. Создание эффективных Win32-приложений с учётом специфики 64-разрядной версии Windows - 2008" - там в главе 6 совсем немного и понятно описано.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008650
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
FIL23
Я так подозреваю надо где то брать Handle и через него убивать.

Это самый ппц метод, обычно после такого проще застрелиться, т.е. перезапустить процесс (не шучу).
Если код убиваемой нити доступен - надо отлаживать, чтобы выход был по сообщению/флажку. Никакого "убиения" быть не должно, это чугуниевый люминь, метод нити должен завершаться сам, без вариантов.
Можно, конечно, рассуждать о том, что есть чужие библиотеки, код которых недоступен, вот тогда можно и отстрелить по хэндлу, это похоже на отстрел собственной ноги бегуна в процессе марафона.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008651
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23Подскажите как корректно и как надо.

Корректно поток убить нельзя. Надо создавать потоки, которые корректно останавливаются
сами по вежливой просьбе извне.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008652
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
корректно останавливаются

скорее, корректно завершаются
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008656
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
Это самый ппц метод, обычно после такого проще застрелиться, т.е. перезапустить процесс (не шучу).
В соседнем топике
https://www.sql.ru/forum/1325656/kak-prervat-vypolneniya-zavisshey-funkcii

некоторые уважаемые мемберы утверждают, что проблемы TerminateThread вполне решаемы и с ними можно жить. Более того, говорят, что вовсю используют этот метод.
Мне слабо верится, хотя я и понимаю, что теоретически это возможно.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008657
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это вы его использованию одного потока учите...
Он до этого ещё не дошёл, у него с переменными беда.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008661
Cobalt747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
FIL23,

Если уж так хочется убивать - то используйте процессы - после них хотя бы память освобождается.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008662
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
некоторые уважаемые мемберы утверждают

ты не юли, ты пальцем покажи на этого гада
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40008664
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Док
YuRock
некоторые уважаемые мемберы утверждают

ты не юли, ты пальцем покажи на этого гада


Это Александр прикалывается: 22211632


Кто не прыгал из окошка
Вместе с маминым зонтом,
Тот лихим парашютистом
Не считается пока.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009053
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cobalt747> Если уж так хочется убивать - то используйте
Cobalt747> процессы - после них хотя бы память освобождается.

+1, кстати. Хоть и не всегда возможно/удобно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009076
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустам
Cobalt747> Если уж так хочется убивать - то используйте
Cobalt747> процессы - после них хотя бы память освобождается.

+1, кстати. Хоть и не всегда возможно/удобно.
Иногда приходится так делать. В случае необходимости использования чужой библиотеки, которая "всё портит".
В принципе, нормально. Главное неудобство - нет доступа к памяти.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009078
Cobalt747
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Гаджимурадов Рустам
Cobalt747> Если уж так хочется убивать - то используйте
Cobalt747> процессы - после них хотя бы память освобождается.

+1, кстати. Хоть и не всегда возможно/удобно.
Иногда приходится так делать. В случае необходимости использования чужой библиотеки, которая "всё портит".
В принципе, нормально. Главное неудобство - нет доступа к памяти.

угу, особенно если эта библиотека (не будем показывать пальцем, но это конечно же pilot_nt.dll) течет памятью.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009079
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cobalt747
течет памятью.
У меня и похуже симптомы бывали.
- Валит исключения наружу (которые, конечно же, не ловятся try..except)
- Закрывает хэндлы выделенных мною (вообще отношения не имеющих к ней) юзер-объектов (эвенты обычно). Предпологаю, что это последствия вызова CloseHandle на мусор из памяти (или затирание переменной с хэндлом вышедшим за пределы массивом, не знаю). Это, конечно, самое страшное поведение, которое я встречал. Десяток разных "багов" в разных местах вылез. Даже клиент СУБД начал падать иногда с GetLastError=6 (ошибка доступа при WAIT_FAILED).
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009085
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не делайте сложных вещей в потоке который планируете небезопасно убивать.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009130
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

Простые потоки не виснут, виснут как раз сложные...
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009146
Fr0sT-Brutal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Видимо, хромиум потому и запускает по процессу на каждую страницу, что они не осилили поймать все возможные баги)) Если глюк - а пох, прибьем и перезапустим процесс.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009153
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Fr0sT-Brutal
Видимо, хромиум

Они и не скрывали это, а даже хвалились, как круто придумали. Правда у меня ощущение, что не они были первооткрывателями. К тому времени движки баз уже так работали.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009163
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman> Правда у меня ощущение, что не они были первооткрывателями.
wadman> К тому времени движки баз уже так работали.

Конечно, не они. Но сравнивать СУБД и ср***й браузер
и хвалиться этим - это как-то совсем через край, ИМХО.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009204
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadman
движки баз уже так работали
да и клиентам порой приходится, зависнуть где-то в дебрях клиентских либ вполне случается...
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009404
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я бы сделал так. Будет работать при флаге freeonterminate := true;
Synchronize конечно тормоз. Но один раз вызвать можно.

Код: 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.
26.
27.
28.
29.
30.
31.
32.
TMyThreadCheckTasks = class(TThread)
     private
     { Private declarations }
      FPredicateComplete: TProc;
      Procedure NotifyComplete();
   protected
     Constructor Create(predicateComplete:TProc);
     procedure Execute; override;
   end;

Procedure Execute;
Begin
Try
 ....
Finally
   Synchronize(NotifyComplete);
End;
End:

Procedure NotifyComplete;
Begin
  If assigned(fpredicatecomplete) then
      Fpredicatecomplete();
End;

//создаём тред 

Mythread := TMyThread.Create(procedure begin MyThread := nil end);

Ну и остановка треда
If assigned (MyThread) then
   MyThread.terminate;
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009406
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если несколько потоков, то стартуем так

threads.Add (TMyThread.Create(procedure (const thread: TMyThread) begin threads.Remove (thread) end)

А остановка потоков тогда будет такая:
// тут ждём, пока все потоки не будут уничтожены
While threads.Count > 0 do begin
If not Threads.First.Terminated then
Threads.First.Terminate;
Sleep(0);
end;
Где threads - TList<TMyThread>
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009560
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О, боже...
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009596
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009599
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А что смешного ? Флаг freeonterminate := true.

Понятно что при freeonterminate := false было бы так

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
While threads.count > 0 
begin
   thread := Threads.first;
   thread.Terminate;
   thread.WaitFor;
   FreeAndNil(thread);
   threads.remove(thread) 
End



И предикат с синхронайзом не нужен.
И замечу мне было лень писать тут код с критическими секциями,
поэтому выбрал синхронайз.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009601
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И уж забота программиста в своём потоке корректно обработать флаг Terminated.
Ржака это когда поток собрались WinApi функциями мочить, вот то ржака.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009609
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mixrud
А что смешного ? Флаг freeonterminate := true.

Понятно что при freeonterminate := false было бы так

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
While threads.count > 0 
begin
   thread := Threads.first;
   thread.Terminate;
   thread.WaitFor;
   FreeAndNil(thread);
   threads.remove(thread) 
End




И предикат с синхронайзом не нужен.
И замечу мне было лень писать тут код с критическими секциями,
поэтому выбрал синхронайз.
Смешного - масса бесполезного кода. Вот, что. Нопы, даже хуже.
Всю эту батарею можно выкинуть, кроме одной строки - FreeAndNil.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009619
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
FreeAndNil(thread);
   threads.remove(thread) 



Отгадайте сами, что удалится из списка... ну и если каждый поток завершается несколько секунд и их много, то ждать придется долго...
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009621
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zelius
Код: pascal
1.
2.
FreeAndNil(thread);
   threads.remove(thread) 




Отгадайте сами, что удалится из списка...
Хорошай баг
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009626
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zelius,

FreeAndNil(thread); принудительно убьет поток. С ошибкой.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009628
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRock,

Поменяй местами.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009629
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zelius,

А вы предпочитаете потерять ссылки на потоки и пускай они завершаются сами по себе??? Ну-ну.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009630
Mixrud
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rgreat,

При freeonterminate true. А я сделал примечание, флаг FreeOnTerminate false.
...
Рейтинг: 0 / 0
как корректно убить поток?
    #40009636
Zelius
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mixrud
Zelius,

А вы предпочитаете потерять ссылки на потоки и пускай они завершаются сами по себе??? Ну-ну.

Я предпочитаю сначала пройтись по всем потокам и сделать Terminate, а уже потом в новом цикле Free, так время ожиданию будет равно времени ожидания самого долгого потока, но не сумме всех потоков
...
Рейтинг: 0 / 0
35 сообщений из 35, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / как корректно убить поток?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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