Форум: "Основная";
Текущий архив: 2004.02.13;
Скачать: [xml.tar.bz2];
Внизкак убить поток из основной программы Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.011 c