Форум программистов, компьютерный форум, киберфорум
Delphi: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 15.06.2016
Сообщений: 11

Кильнуть собственный тред

15.06.2016, 09:20. Показов 1337. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Господа!

Требуется кильнуть тред (TThread), запущенный в своем процессе.
Есть такой код, которым в свое время пользовался успешно для киляния процессов. Так вот, с собственным тредом он не работает.
Delphi
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
Var
 hToken:THandle;
 hProcess:THandle;
 tkp:TTokenPrivileges;
 buffer:DWord;
 iErr:integer;
 
// вот тут возникает ошибка "Неверный дескриптор" в обоих случаях:
if not Windows.OpenProcessToken(Thread.ThreadID,TOKEN_ADJUST_PRIVILEGES,hToken) ...
// if not Windows.OpenProcessToken(Thread.handle,TOKEN_ADJUST_PRIVILEGES,hToken)
 
// Ну а дальше идти смысла нет...
 
if not Windows.LookupPrivilegeValue(nil,'SeDebugPrivilege',tkp.Privileges[0].Luid)...
tkp.PrivilegeCount:=1;
 tkp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
 if not Windows.AdjustTokenPrivileges(hToken,FALSE,tkp,0,nil,buffer)...
Windows.CloseHandle(hToken);
CloseHandle(Thread.ThreadID);
 hProcess:=OpenProcess(PROCESS_TERMINATE,true,Thread.ThreadID);
 if hProcess<>0 then
                begin
                TerminateProcess(hProcess,0);
                CloseHandle(hProcess);
                end
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.06.2016, 09:20
Ответы с готовыми решениями:

Автосигнализаций тред
Приветствую. Недавно стал обладателем 1118 модели автоваза, немного копнул на тему дистанционных открывалок дверей. И, честно говоря,...

Динозавров тред
У кого какой степени динозавровости машинка, на которой вы работаете? Конфигурация обязательна! Лучше по шаблону: CPU =...

Собственный справочник :)
Уважаемые программисты есть предложение которое пригодится большинству участников форума. А именно создать справочник по классам и...

14
Заблокирован
19.07.2016, 18:43
Ну естественно, потому, что Вы, очевидно, передаёте MainThreadId, вместо PID.

Code
1
2
3
4
5
6
procedure TForm1.Button1Click(Sender: TObject);
const
  PROCESS_TERMINATE = $0001;
begin
  TerminateProcess(OpenProcess(PROCESS_TERMINATE,BOOL(0),GetCurrentProcessId),0);
end;
0
0 / 0 / 0
Регистрация: 15.06.2016
Сообщений: 11
19.07.2016, 20:34  [ТС]
А всё оказалось просто:

TerminateThread(Thread.Handle,0);
0
12 / 12 / 5
Регистрация: 03.06.2016
Сообщений: 169
02.09.2016, 21:49
Зачем же так жестко с процессом то, а если в этот момент процессу что то мешать будет. Не лучше послать процессу ивент на закрытие.
0
0 / 0 / 0
Регистрация: 15.06.2016
Сообщений: 11
03.09.2016, 15:49  [ТС]
Это все понятно, эвент посылаеццо, но если он после некоторого таймаута не застопарился, значит всё.
0
12 / 12 / 5
Регистрация: 03.06.2016
Сообщений: 169
03.09.2016, 20:10
Если ивент послан, а он не закрылся значит где то ошибка, а всякими TerminateThread вы только аксес валейшен получите.
1
0 / 0 / 0
Регистрация: 15.06.2016
Сообщений: 11
04.09.2016, 09:44  [ТС]
Простейший пример. Тред обращается к какому-то серверу по Интернету - для чего и писался.
Сервер завис или пинг исчез, а прогу закрывать надо, она работает по расписанию. Таймаута от сервера ждать некогда. Вот поэтому подобные обращения и пишу тредами, чтобы можно было их кильнуть и хоть прогу завершить корректно.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
04.09.2016, 09:53
ymv, тебе надо тогда делать terminate всему процессу, а не отдельному потоку.
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
04.09.2016, 09:59
Цитата Сообщение от ymv Посмотреть сообщение
Требуется кильнуть тред (TThread), запущенный в своем процессе.
Специально для этой задачи у TThread имеется метод Terminate();
0
0 / 0 / 0
Регистрация: 15.06.2016
Сообщений: 11
04.09.2016, 11:47  [ТС]
>тебе надо тогда делать terminate всему процессу, а не отдельному потоку.

Нет, не надо. Весь процесс - это прога, она должна корректно завершиться. Тред обращается к серверу в Интернете, он может подвиснуть, но прога висеть не должна. Teleport Pro юзал, надеюсь? Там тот же принцип: 10 тредов качают, головной процесс ими управляет.

>Специально для этой задачи у TThread имеется метод Terminate();

Будет работать, когда тред висит? Suspend() точно не работает в этом случае, тред тут должен реагировать на эвенты. Terminate() уж не помню, пробовал, нет, наверно тоже самое.

Добавлено через 5 минут
P.S. Ну да, Terminate() в этой ситуации точно работать не будет, судя по описалову:

>Terminate sets the thread's Terminated property to true, signaling that the thread should be terminated as soon as possible.

Знаем, играли. Когда тред висит в описанной выш5е ситуации, штатные методы TThread не работают.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
04.09.2016, 11:53
Цитата Сообщение от ymv Посмотреть сообщение
Весь процесс - это прога, она должна корректно завершиться.
Так в том-то и дело, что если прибить один из потоков, гарантии корректного
завершения всей программы уже нету. Например, поток может быть убит при
захваченной блокировке LoaderLock в ntdll (она захватывается при загрузке/
выгрузке dll, при запуске и уничтожении потоков, при вызове RtlUnwind на x64 и
некоторых других функциях). В итоге при завершении программы штатными
методами процесс легко может повиснуть или выкинуть еще какую-нибудь штуковину.
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
04.09.2016, 13:45
Цитата Сообщение от ymv Посмотреть сообщение
Знаем, играли. Когда тред висит в описанной выш5е ситуации, штатные методы TThread не работают.
Ну приделай к ней свой метод который ее через TerminateThread похоронит. Только такое ее снятие очень не полезное для системы.

Добавлено через 4 минуты
Цитата Сообщение от ymv Посмотреть сообщение
Тред обращается к какому-то серверу по Интернету - для чего и писался.
В дельфе у всех средств работы с инетом и сокетами асинхронная работа и таймауты реализованы прекрасно. Так же как и в WinAPI. Что там настолько нештатное что понадобилось с потоками висящими на синхронных вызовах лисапед лисапедить?
0
0 / 0 / 0
Регистрация: 15.06.2016
Сообщений: 11
04.09.2016, 14:44  [ТС]
>Что там настолько нештатное что понадобилось с потоками висящими на синхронных вызовах лисапед лисапедить?

Да не то чтобы настолько нештатное, просто на автомате всегда так делаю. Может подвиснуть или что - надо делать тредом и его килять во внештатных ситуациях. Тем более эта утиль предназначена для пакетной работы, значит должна работать как часы. И работает.

И не такая уж надёжная штука дельфя и винды, чтобы говорить, что не повиснет. Как минимум подстраховаться надо.

>при захваченной блокировке LoaderLock в ntdll (она захватывается при загрузк...

Ничего такого системного там нет. Никаких "глобальных" блокировок. Тред предельно изолирован.
0
 Аватар для Fulcrum_013
2083 / 1574 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
04.09.2016, 15:01
Цитата Сообщение от ymv Посмотреть сообщение
Может подвиснуть или что - надо делать тредом и его килять во внештатных ситуациях
касательно сокетов, инет дел и всего что может работать асинхронно это very very bad practicle.

Добавлено через 2 минуты
Цитата Сообщение от ymv Посмотреть сообщение
Как минимум подстраховаться надо.
В винапи подстраховано гораздо надежней и спящим тредом. На самом деле все синхронные варианты функций работают ожиданием события от асинхронного варианта.

Добавлено через 4 минуты
Дельфи в этом плане только оборачивает WinAPI

Добавлено через 1 минуту
Единственное что реально требует такого подхода с потоком для таймаута - работа с COM и LPT портами там асинхронных вариантов почему то нет.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
04.09.2016, 15:35
Цитата Сообщение от ymv Посмотреть сообщение
Ничего такого системного там нет. Никаких "глобальных" блокировок. Тред предельно изолирован.
Во-первых, при уничтожении треда не вызывается DLL_THREAD_DETACH в dll, а значит,
если с потоком были связаны какие-то данные (хранящиеся, например, в TLS), то
они освобождены не будут. Вот и утечка уже.

Во-вторых, полностью изолированных потоков в Win32 не может быть по определению, а
захват ntdll!LoaderLock выполняется намного чаще, чем обычно принято думать.

В-третьих, даже если поток кажется зависшим, все равно нет никакой гарантии, что он
не "развиснет" одновременно с вызовом TerminateThread. И тогда может быть, что
поток прибьют как раз в тот момент, когда он выполняет метод какого-нибудь объекта, в
результате чего объект останется в неопределенном состоянии.

Я таких багов за последние годы повидал сотню, если не больше: сначала кто-то
делает "безобидный" kill потоку в одном месте, а валится потом в совсем другом,
иногда минуты или часы позже.

Так что я все равно буду нудно талдычить, что TerminateThread - это последнее
средство, крайняя мера, и после него состояние всего процесса неопределено,
можно сразу делать TerminateProcess.

----

Ладно, если уже на то пошло и кроме TerminateThread совсем-совсем ничего нет,
тогда надо прибивать поток, только делать это по-другому, более безопасным способом.
Например, сделать для потока SetThreadContext, направив его в какую-нибудь
функцию, где он сможет сам для себя вызвать ExitThread и, соответственно, вызвать
все нужные деструкторы и нотификаторы DLL_THREAD_DETACH.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.09.2016, 15:35
Помогаю со студенческими работами здесь

Собственный youtube
Господа, как сделать так, что видео-файлы, загруженные на сервер, можно было смотреть в браузере с использованием потокового протокола? ...

Собственный ProgressBar
Здравствуйте! Собственно суть такова, что мне нужно, что бы в прогресс баре в зависимости от значения рисовался прямоугольник (т.е....

Собственный сервис
Требуется написать пару сервисов. Первый - пустой (ничего не делает), при запуске должен очутиться в списке запущенных сервисов. Второй...

Собственный вектор
Здравствуйте, подскажите как найти матрицу для собственного вектора ? (-1) 1 -1 Добавлено через 13 минут +вопросик ) если...

Собственный хостинг???
Здравствуйте, народ! Пожалуйста, проконсультируйте. Каким образом можно создать свой собственный хостинг? Я имею ввиду абсолютно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru