Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.13;
Скачать: CL | DM;

Вниз

как убить поток из основной программы   Найти похожие ветки 

 
AlexanderS   (2004-02-03 13:56) [0]

thread.terminate не подходит поскольку код большой, рекурсивный и запутанный и на каждом углу проверять if terminated идея плохая.

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


 
TUser ©   (2004-02-03 14:07) [1]

suspend, resume ?


 
Digitman ©   (2004-02-03 14:10) [2]


> на каждом углу проверять if terminated идея плохая


настолько же плохая как и "на каждом углу" делать PeekMessage(WM_QUIT)

но ни без той ни без другой действительно корректное терминирование поточной ф-ции невозможно


 
Digitman ©   (2004-02-03 14:13) [3]

а уж при рекурсии-то сам бог велел легко и просто организовать проверки на любой признак терминирования

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


 
AlexanderS   (2004-02-03 14:43) [4]

это ж извращение по-моему...

послать thread.terminate, потом отлавливать по коду terminated, если оно отловится на тридцать-энном уровне рекурсии корректно вывести его оттуда, что займет приличное время, в основной программе отслеживать действительно ли он завершился и только потом запускать заново... мдя. помнится в досе потоки организовывались подобными методами. спрашивается где прогресс =)


 
Verg ©   (2004-02-03 14:50) [5]


> помнится в досе потоки организовывались подобными методами.
> спрашивается где прогресс =)


Да? А ты помнишь как в дос-е организовывалось одновременное выполнение многих потоков с распределением времени?


 
Тимохов ©   (2004-02-03 14:52) [6]


> помнится в досе потоки организовывались

А в досе были потоки?
Чессно слово не знал (или забыл) :((


 
Verg ©   (2004-02-03 14:55) [7]


> если оно отловится на тридцать-энном уровне рекурсии корректно
> вывести его оттуда, что займет приличное время,


procedure RecursProc;
begin
if terminated then Abort;
......
....
end;

try
RecursProc;
except
on EAbort: заканчиваем обработку этих данных, начинаем ждать новые
......
end;


 
Verg ©   (2004-02-03 14:57) [8]


> Тимохов © (03.02.04 14:52) [6]
>
> > помнится в досе потоки организовывались
>
> А в досе были потоки?
> Чессно слово не знал (или забыл) :((


Ну один-то точно был :))


 
Digitman ©   (2004-02-03 14:58) [9]


> AlexanderS



> это ж извращение по-моему


судя по твоей логике, Борланд, реализовавший метод Application.Run, в котором делается по сути то же самое (в части "отлова команд" на терминирование процесса), но в осн.код.потоке - первый извращенец на этом поприще))


 
AKul ©   (2004-02-03 15:01) [10]


> AlexanderS (03.02.04 13:56)

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


> AlexanderS (03.02.04 14:43) [4]
> это ж извращение по-моему...
> послать thread.terminate, потом отлавливать по коду terminated,

А зачем в таком случае Windows посылает сообщения типа WM_QUIT, WM_CLOSE, WM_CLOSEQUERY....., которые все-равно отлавливаются в Вашей программе?
Неужели и это похоже на изврат?


 
AlexanderS   (2004-02-03 15:55) [11]

ясно. в общем корректо завершить работу можно только изнутри самого потока... печально )

>> Да? А ты помнишь как в дос-е организовывалось одновременное >> выполнение многих потоков с распределением времени?

не только помню но и делал это. собственно сейчас переношу на windows программу которая писалась... эмм... шесть лет назад на TP7.

>> А зачем в таком случае Windows посылает сообщения типа
>> WM_QUIT, WM_CLOSE, WM_CLOSEQUERY....., которые все-равно
>> отлавливаются в Вашей программе?

так они же не моей программой непосредственно отлавливаются. думаю мало кто занимается мазохизмом в особо запущенных случаях самостоятеьно отлавливая подобные сообщения. да и события приложения - у вас же по программе не раскидано везде где можно предусмотреть нажатие кнопки If ButtonPressed then и т.п., вместо этого используется OnPress.

если действительно невозможно убить поток из основной программв мне кажется это упущением, надо было предусмотреть такую возможность...


 
AKul ©   (2004-02-03 16:24) [12]


> AlexanderS (03.02.04 15:55) [11]
> ясно. в общем корректо завершить работу можно только изнутри
> самого потока... печально )


Корректно - Да, а вот некорректно - TerminateThread из любого потока.


> >> WM_QUIT, WM_CLOSE, WM_CLOSEQUERY....., которые все-равно
> >> отлавливаются в Вашей программе?
>
> так они же не моей программой непосредственно отлавливаются.

А кем тогда, разрешите спросить, если не Вашей программой????????


> если действительно невозможно убить поток из основной программв
> мне кажется это упущением, надо было предусмотреть такую
> возможность...

Так и предусмотрели - TerminateThread.
А как его можно корректно прервать из другого потока, если не всегда известно, что он уже "сделал" , а что нет?


 
Digitman ©   (2004-02-03 16:40) [13]


> AlexanderS (03.02.04 15:55) [11]



> не только помню но и делал это


писал ты, очевидно, эмулятор многозадачности в однозадачной системе, не более того


> так они же не моей программой непосредственно отлавливаются


твоей)... но выполняемой под управлением кода от Борланда, который чуть облегчил тебе жизнь и не заставляет тебя в общих случаях думать о цикле выборки/диспетчеризации сообщений


> вместо этого используется OnPress


то же самое с легкостью делается в любом код.потоке


> мне кажется это упущением


TerminateThread и есть аварийный способ
а все что неаварийно, должнло быть предусмотренно именно тобой


 
Владислав ©   (2004-02-03 16:49) [14]

Ну так генерируй свое исключение. На самом верхнем уровне обрабатывай свое исключение и выходи из потокового метода Execute.


 
AlexanderS   (2004-02-03 16:58) [15]

а вот теоретически интересно, можно узнать работает поток в данное время или уже закончил свою работу. понаслушавшись вас я уже сам предусмотрел это, но всё же?


 
Digitman ©   (2004-02-03 17:02) [16]

можно.
посмотри как реализован метод TThread.WaitFor - по кр.мере концептуально просветишься на эту тему


 
AKul ©   (2004-02-03 17:11) [17]


> AlexanderS (03.02.04 16:58) [15]
> а вот теоретически интересно, можно узнать работает поток
> в данное время или уже закончил свою работу

Можно конечно:
1. Использовать свою глобальную переменную-флаг.
2. Вызвать функцию GetExitCodeThread, которая в случае незавершенного потока вместо кода завершения вернет STILL_ACTIVE.

Дождаться полного завершения потока после вызова метода Terminate (ExitThread) можно с помощью WaitFor (для VCL)
или WaitForSingleObject (API)


 
Erik ©   (2004-02-03 17:45) [18]

С реурсией тебе уже подсказали как поступить.
В остальных случиях если ты использовал
Status := WaitForMultipleObjects(Ord(High(tmEvent.Event)) + 1,
@tmEvent.Event, false, INFINITE);
То можно разбить обработку твоего алгоритма на мелкие части. И после завершения работы куска алгоритма выставлять соответствующее событие. И получится все очень просто.
case TActivEvent(Status) of
actExit: FinallExit;
actTest: FetchInfo;
actAlg1: Alg1;
actAlg2: Alg2;
...............
else
if Status = WAIT_TIMEOUT then
Beep; //или что душе угодно
end;



Страницы: 1 вся ветка

Текущий архив: 2004.02.13;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.026 c
3-38719
alekst
2004-01-22 10:54
2004.02.13
выполнение Запроса


1-38926
Настенька
2004-02-04 12:10
2004.02.13
проследить нажатие кнопки


14-39015
TGrigory
2004-01-22 22:18
2004.02.13
Компонет для отображения лога чата


1-38906
Grinder
2004-01-29 16:47
2004.02.13
Control UpDown has no parent window


6-38987
X-Disa
2003-12-12 08:22
2004.02.13
Скан сети