Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / как корректно убить поток? / 25 сообщений из 35, страница 1 из 2
14.10.2020, 21:18
    #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
14.10.2020, 21:44
    #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
14.10.2020, 22:01
    #40008648
ъъъъъ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как корректно убить поток?
FIL23,

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

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

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

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

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

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

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

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

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


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


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

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

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

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

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

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

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

Конечно, не они. Но сравнивать СУБД и ср***й браузер
и хвалиться этим - это как-то совсем через край, ИМХО.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16.10.2020, 13:25
    #40009204
vavan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как корректно убить поток?
wadman
движки баз уже так работали
да и клиентам порой приходится, зависнуть где-то в дебрях клиентских либ вполне случается...
...
Рейтинг: 0 / 0
17.10.2020, 02:22
    #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
17.10.2020, 02:43
    #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
18.10.2020, 10:46
    #40009560
YuRock
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как корректно убить поток?
О, боже...
...
Рейтинг: 0 / 0
18.10.2020, 16:15
    #40009596
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как корректно убить поток?
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / как корректно убить поток? / 25 сообщений из 35, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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