Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.03.03;
Скачать: [xml.tar.bz2];

Вниз

Мониторинг состояния Thread а   Найти похожие ветки 

 
Владимир Березин   (2004-02-17 18:45) [0]

Привет всем!
Ребята, помогите пожалуйста решить вот такую порблему.
Приложение содержит юнит с формой и отдельный юнит в
котором работает Thread с установленным в TRUE свойством
FreeOnTerminate. Поток автономен и о форме ничего знать
не должен.
На форме стоит Timer который должен постоянно мониторить
состояние потока и отловить момент когда тот выполнит метод Execute и грохнется. Вопрос - как это сделать?


 
Тимохов   (2004-02-17 18:48) [1]

сделать переменную, в которой устанавливать в событии потока OnTermination флажок того, что поток закончился. Защищать место установки флажка критической секцией. Соответственно обращаться к флажку также под защитой крит. секции. Можно и по-другому. Это просто первое рабочее решение, пришедшее в голову.


 
Verg   (2004-02-17 20:01) [2]


> Тимохов © (17.02.04 18:48) [1]


Про критические секции в событии OnTerminate обоснуйте, пожалуйста.


 
Семен Сорокин   (2004-02-17 20:05) [3]

Владимир Березин (17.02.04 18:45)
Я обычно посылал сообщение WM_THREAD_DONE = WM_USER + 1 в OnDestroy потока своему окну, где обрабатывал его должным образом.


 
Тимохов   (2004-02-18 14:02) [4]


> Verg © (17.02.04 20:01) [2]

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


 
panov   (2004-02-18 14:10) [5]

Взвести семафор или Event, передать его в поток, в нем сбросить.


 
Digitman   (2004-02-18 14:15) [6]

самое корректное решение - мониторинг интересующего доп.потока в контексте другого доп.код.потока, который будет в цикле вызывать MsgWaitForMultipleObjects(1, TargetThreadHandle, ...), отслеживая реальный момент завершения TargetThread и оперативно реагируя при этом на сообщения


 
Polevi   (2004-02-18 14:41) [7]

>Владимир Березин (17.02.04 18:45)
на мой взгляд проще всего использовать [3], при старте передавать потоку id сообщения и хэндл окна получателя


 
Юрий Зотов   (2004-02-18 16:00) [8]

Елы-палы, во наговорили-то... Народ, вы че?

Читаем вопрос - нужно отловить, когда поток вышел из Execute и грохнулся. Всего-то навсего.

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

Какие таймеры? Какие критические секции? Какие сообщения? Какие семафоры и Event"ы? Какие дополнительные потоки?

Народ, вы че?


 
Тимохов   (2004-02-18 16:06) [9]


> Юрий Зотов © (18.02.04 16:00) [8]

Юрий, Вы как всегда правы :))))))

Но с семафорами тоже ведь можно :)))))


 
Digitman   (2004-02-18 16:10) [10]


> Юрий Зотов © (18.02.04 16:00) [8]


Юрий, видимо автор наивно полагает, что поток "грохается" именно тогда, когда метод Execute вернул управление.. т.е. фактом завершения поточной ф-ции явл-ся факт завершения выполнения метода Execute

ты прекрасно знаешь, что это не так

факт действительного "гроханья" потока можно определить только вызвав одну из ф-ций ожидания срабатывания объекта синхронизации, каковым явл-ся хэндл потока


 
Digitman   (2004-02-18 16:14) [11]

есть, правда, еще один вариант - локальный перехват ExitThread()


 
Тимохов   (2004-02-18 16:19) [12]


> Digitman © (18.02.04 16:10) [10]

Если почитать внимательно вопрос, то становится не очень понятно, чего хочет автор.
Одно дело, если он хочет действительно узнать, что поток грохнулся (не ясно зачем ему это). Другое дело, если он хочет знать, что действие execute завершилось (например, интеграл посчитался или файл считался) - в этом случае можно, напирмер, в помощью крит. секции утановить флажок. ИМХО здесь нужно немного лучше знать, что действительно хочет автор.

Или я что-то недопонимаю?


 
Verg   (2004-02-18 16:22) [13]

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


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


OnTerminate здесь более, чем "за глаза".
Событие синхронизировано с гл. потоком - чего еще надо?


 
Digitman   (2004-02-18 16:25) [14]

не знаю ... не знаю ...
судя по термину "грохнулся" компетенция автора в данном вопросе оставляет желать лучшего ..

а уточнять он, видимо, не намерен


 
AKul   (2004-02-18 16:27) [15]


> Юрий Зотов © (18.02.04 16:00) [8]
> OnTerminate - и все. Сам факт захода в этот обработчик уже
> и означает, что "поток вышел из Execute и грохнулся".


Не согласен!
Факт захода в этот обработчик означает выход из Execute, но никак не его "грохание". Ибо код этого обработчика (OnTerminate) выполняется все-равно ЭТИМ ПОТОКОМ.


 
Verg   (2004-02-18 16:31) [16]


> Ибо код этого обработчика (OnTerminate) выполняется все-равно
> ЭТИМ ПОТОКОМ.


1. Каким "этим"? Уточните. Код OnTerminate выполняет главный поток.
2. Как это связано с "гроханием"? Уничтожение объекта thread, который завершился будет выполнено ядром по закрыванию его handle всеми "заинтересованными лицами".


 
Тимохов   (2004-02-18 16:32) [17]

Думаю, что здесь самый правый 14.


 
Юрий Зотов   (2004-02-18 16:44) [18]

> AKul © (18.02.04 16:27) [15]
> Не согласен!

Печально. Потому что OnTerminate все же выполняется уже главным потоком. А FreeOnTerminate (cм. вопрос) означает, что искомый поток таки именно грохнулся.

> All

И для практической программы совершенно неважно, уже он грохнулся, или вот-вот грохнется. Для практической программы важно лишь то, что все прикладные действия, закодированные в Execute, уже выполнены. А все прочие детали (ТОЧНЫЙ момент завершения функции потока, ТОЧНЫЙ момент освобождения занятой объектом памяти и пр.) представляют собой чисто академический интерес.


 
Digitman   (2004-02-18 16:51) [19]


> Юрий Зотов © (18.02.04 16:44) [18]


для рада случаев - не согласен

или в борландовским спецам делать нечего было, как только TThread.WaitFor реализовывать


 
AKul   (2004-02-18 17:42) [20]


> Юрий Зотов © (18.02.04 16:44) [18]

Исходный текст процедуры потока (передается в CreateThread):
function ThreadProc(Thread: TThread): Integer;
var
FreeThread: Boolean;
begin
try
Thread.Execute;
finally
FreeThread := Thread.FFreeOnTerminate;
Result := Thread.FReturnValue;
Thread.FFinished := True;
Thread.DoTerminate; // Здесь произойдет вызов
// обработчика события OnThread
// этим потоком
// (через Synchronize, конечно)
if FreeThread then Thread.Free;// А сюда мы не возвратимся
// пока главный поток
// не отработает метод,
// присвоенный OnThread
// (сам обработчик)
EndThread(Result); // А вот где поток "грохается"
end;
end;

Как видите, в момент обработки события, закрепленного за OnTerminate, этот поток будет еще "жив"


> А FreeOnTerminate (cм. вопрос) означает, что искомый поток
> таки именно грохнулся.

Нет, FreeOnTerminate никак не влияет на "грохание" потока.
При FreeOnTerminate=true уничтожается класс TThread,а не поток!!!
Поток "грохнется" вызовом EndThread (см. исходный текст) в любом случае (не зависимо от FreeOnTerminate).


 
Юрий Зотов   (2004-02-18 18:20) [21]

> AKul © (18.02.04 17:42) [20]

Про то, что класс TThread отличается от потока Windows, мне рассказывать не нужно. Чем отличается - тоже не нужно.

Вы сказали: "Ибо код этого обработчика (OnTerminate) выполняется все-равно ЭТИМ ПОТОКОМ". Эту фразу я понял так: код обработчика события OnTerminate выполняется в контексте того же потока Windows, что и код метода Execute. То есть, в рамках одной и той же потоковой функции.

Теперь два вопроса, чтобы не было недопонимания:
1. Я правильно Вас понял?
2. Если да, то продолжаете ли Вы настаивать на своих словах?

И (поскольку чую, что спор будет длинным), два предложения - чтобы тоже не было недопонимания:
1. Слова "грохнется", "уничтожится" и т.п. больше не произносим ни в каких вариациях, поскольку они имеют неоднозначный смысл.
2. Вместо этого пользуемся однозначными терминами "завершение метода Execute", "завершение потоковой функии" и "уничтожение объекта TThread".


 
Verg   (2004-02-18 18:23) [22]


> 1. Слова "грохнется", "уничтожится" и т.п. больше не произносим
> ни в каких вариациях, поскольку они имеют неоднозначный
> смысл
.


Вот, вот. Из-за этого весь этот спор...


 
Digitman   (2004-02-18 18:30) [23]

я вот себе думаю одно - автор ассоциирует "грох" потока с возвратом из Execute

пока иного авторского мнения я не знаю..


 
Тимохов   (2004-02-18 18:32) [24]


> грох" потока с возвратом из Execute

А может просто с окончанием, т.е. доходом до конца?


 
Digitman   (2004-02-18 18:33) [25]


> Тимохов © (18.02.04 18:32) [24]



> А может просто с окончанием, т.е. доходом до конца?


до чьего ?) ... тоже вопрос))))


 
Verg   (2004-02-18 18:40) [26]

А автор уже давным-давно, услышав все что он хотел, занимается своими делам.... И нет ему уже дела до того, что тут народ "надрывается" :))


 
Digitman   (2004-02-18 18:44) [27]

Вовааааа ! Отзовиииись !!!!

тута народ пупки вже надорвал на пути к истине) ... который ты туманно обозначил дланью своей)))


 
Тимохов   (2004-02-18 18:50) [28]


> Вовааааа ! Отзовиииись !!!!
>
> тута народ пупки вже надорвал на пути к истине) ... который
> ты туманно обозначил дланью своей)))


Вот она суть форума - найти истину :)))))))
Полностью согласен с 26


 
WebErr   (2004-02-18 18:58) [29]

Мдаа!!! Полемика! Может лучше мне с DBGrid"oм поможите - я в основной!


 
Тимохов   (2004-02-18 19:01) [30]


> поможите - я в основной!

А мы где?


 
kull   (2004-02-18 19:08) [31]

Я думаю, что если автор таймером собирается отлавливать завершение... чего - не важно. Вполне можно и OnTerminate обойтись. И не заморачиваться следующим: конца потока-объекта или конца потока-метода надо ждать.


 
Юрий Зотов   (2004-02-18 19:56) [32]

> kull © (18.02.04 19:08) [31]

Вот в ЭТОМ я с Вами совершенно согласен. О чем и написал в [8], а затем другими словами повторил в [18]. Автору надо ЗАДАЧУ решить. Просто и надежно. И все. Прочие тонкие материи его на сегодня не интересуют.


 
Владимир Березин   (2004-02-18 21:09) [33]

Привет!
Извиняюсь, что вчера не посмотрел ответы на заданный мной
вопрос - Весь вечер не мог с Вами связаться, видимо у Вас
на сервере были какие - то порблемы.

Почитав развернувшуюся дискуссию я вижу необходимость
сформулировать задачу по другому. так вот:
Имеется список заданий на загрузку файлов из интернета. Каж
дое задание выполняется в отдельном потоке, а приложение
должно только запустить задание, в порцессе работы отслежи
вать и отображать в окне текущее состояние и узнать когда за
дание будет выполнено и не должно заботиться об уничтожении
завершившего свою работу потока.


 
Юрий Зотов   (2004-02-18 22:45) [34]

> Владимир Березин (18.02.04 21:09) [33]

> список заданий
var
JobList: TThreadList;
(Cоздать в initialization, убить в finalization - предварительно выдав Terminate всем потокам в JobList и дождавшись их завершения)

> Каждое задание выполняется в отдельном потоке
Пишем общий для всех заданий класс потока:
конструктор - добавить Self в JobList
деструктор - удалить Self из JobList
Execute - выполнение задания. Периодически проверяется Terminate и в главную форму посылается (строго через PostMessage) сообщение WM_USER+100, в параметрах которого передаются Self и информация о текущем состоянии задания. Получив сообщение, форма знает о задании ВСЕ и может отобразить ход его выполнения.

> узнать когда задание будет выполнено
Общий для всех потоков обработчик OnTerminate. В нем Sender - это завершившийся поток.

> и не должно заботиться об уничтожении завершившего свою работу
> потока.
Можно проставить FreeOnTerminate = True, а можно в том же OnTerminate написать одну-единственную строчку
TThread(Sender).Free. Второе надежнее - до этого вызова Sender уж точно не будет битой ссылкой и с ним можно безопасно работать.


 
Владимир Березин   (2004-02-18 23:00) [35]

>>Юрий Зотов [34]

Все понял! Спасибо!


 
AKul   (2004-02-19 09:24) [36]


> Юрий Зотов © (18.02.04 18:20) [21]


> Вы сказали: "Ибо код этого обработчика (OnTerminate) выполняется
> все-равно ЭТИМ ПОТОКОМ".


Согласен с замечаниями по поводу этой фразы, (сам только что ВНИМАТЕЛЬНО прочитал ее).
"ЭТИМ ПОТОКОМ" я хотел подчеркнуть, что вызов события, закрепленного за OnThread, происходит именно этим, все еще "живым", потоком (понятно, что выполняться он будет контекстом первичного (главного) потока, а этот поток будет приостановлен до завершения обработки этого события главным потоком. Это, ктасти, я уже писал в посте [20]).


> 1. Слова "грохнется", "уничтожится" и т.п. больше не произносим
> ни в каких вариациях, поскольку они имеют неоднозначный
> смысл.


Согласен, что больше не произносим, но ведь везде упоминалось слово поток, а не класс потока - это, согласитесь, разные вещи!!! Так что "грохнется" или "уничтожится" поток - фактически одно и то же (поток - это же "стандартное" название объекта ядра поток (thread)).


> 2. Вместо этого пользуемся однозначными терминами "завершение
> метода Execute", "завершение потоковой функии" и "уничтожение
> объекта TThread".

Хорошо, если использовать термин "завершение метода Execute", то согласен, событие, закрепленное за OnThread, вызовется после этого.
Но с терминами "завершение потоковой функии" и "уничтожение объекта TThread" никак нет, ибо они произойдут после обработки события, закрепленного за OnThread.



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

Форум: "Основная";
Текущий архив: 2004.03.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.011 c
1-6030
Незнающий
2004-02-18 16:48
2004.03.03
Как в TListBox отследить изменение текущего элемента (ItemIndex)?


3-5962
lightix
2004-02-05 13:03
2004.03.03
Выборка из DBF


14-6197
Nikolay M.
2004-02-10 10:00
2004.03.03
Кто за электробритву скажет?


3-5971
ivs13
2004-02-05 14:09
2004.03.03
Бесплатная лицензия на Yaffil


1-6121
Creator
2004-02-20 15:54
2004.03.03
Как зделать System процесс в ХР





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский