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

Вниз

Узнать о завершении работы потока, как?   Найти похожие ветки 

 
tipman ©   (2009-12-29 11:51) [0]

Есть основной поток, из него создаю ещё один. Он отрабатывает и завершается сам, т.е. FreeOnTerminate = true. Мне его завершать не надо. Как узнать из основного потока, закончил ли выполнение созданный, стандартными средствми? На данный момент есть переменная, которая в create потока устанавливается в true, в конце Execute, ну или OnTerminate она ставится в false. Думал если он завершается и должен сам разрушаться, попробвать проверить на nil - не тут то было, дескриптор не очищается. Как то можно это сделать не добавлением переменных а какой нить проверкой стандартного свойства скажем или типа того


 
Sergey Masloff   (2009-12-29 11:54) [1]

Послать сообщение основному потоку при завершении?


 
Сергей М. ©   (2009-12-29 12:14) [2]

> Он отрабатывает и завершается сам, т.е. FreeOnTerminate = true

Убирай FreeOnTerminate = true.

В осн.потоке вызывай

MyThread.WaitFor;
.. здесь доп.поток ГАРАНТИРОВАННО завершил свое исполнение ..
MyThread.Free; //а здесь он прекратил свое существование


 
Медвежонок Пятачок ©   (2009-12-29 12:28) [3]

легче тогда и сам поток убрать. и ждать ничего не придется.


 
~AQUARIUS~ ©   (2009-12-29 20:02) [4]

TThread.OnTerminate?


 
Сергей М. ©   (2009-12-29 21:20) [5]

Ишшо один)


 
tipman ©   (2009-12-30 12:53) [6]

Сергей М.

Мне нужно чтобы основной поток тоже работал, а не тормозил, с WaitFor он засыпает. Т.е. опять же тольло либо с симафорами, либо сообщениями? Больше никак?


 
Сергей М. ©   (2009-12-30 13:19) [7]


> Мне нужно чтобы основной поток тоже работал


Можно поступить так - как только осн.потоку будет нефига делать и он остановится "покурить", возникнет событие Application.OnIdle.
В его обработчике ты волен проверить, не закруглился ли на сей момент твой доп.поток по хозяйству, и если закруглился то уничтожить его.

Примерно так:

with MyThread do
try
 GetExitCodeThread(.CheckThreadError(GetExitCodeThread(Handle)<>0);
// доп.поток гарантированно закруглился - здесь можно забрать у него результаты работы
// перед тем как уничтожить его
 Free; // уничтожение доп.потока
except
 on EThread do; // доп.поток еще жив и трудится
else
 raise; // произошло что-то еще, например, ты забыл или не захотел убрать строчку FreeOnTerminate := True    -  получи букет граблей
end;



 
Сергей М. ©   (2009-12-30 14:55) [8]

with MyThread do
try
CheckThreadError(GetExitCodeThread(Handle)<>0);


 
Rouse_ ©   (2009-12-30 17:29) [9]

Ну для проверки из вне жив или нет, достаточно сказать GetThreadContext (или вариации OpenThread и т.п.)


 
Сергей М. ©   (2009-12-30 21:18) [10]


> достаточно сказать GetThreadContext (или вариации


Нахрена ? Если персонально полученный хендл треда прямо перед носом ?


 
Юрий Зотов ©   (2009-12-31 10:45) [11]

Чего-то я не понимаю, наверное. Решение-то самое стандартное и лежит на поверхности - так на фига же извращаться?

FThread := TMyThread.Create(True); // FThread - поле формы.
FThread.FreeOnTerminate := True;
FThread.OnTerminate := ThreadTerminate; // ThreadTerminate - метод формы
FThread.Resume;

procedure TForm1.ThreadTerminate(Sender: TObject);
begin
 FThread := nil
end;

Теперь в любом месте можно проверить поле FThread - если оно не nil, то поток еще работает. И все дела.


 
Rouse_ ©   (2010-01-01 02:36) [12]


> Сергей М. ©   (30.12.09 21:18) [10]
> Нахрена ? Если персонально полученный хендл треда прямо
> перед носом ?

Сереж, не пыли. Это был ответ на вопрос "Как узнать из основного потока, закончил ли выполнение созданный, стандартными средствми".

Под стандартными средствами я подразумеваю нечто уже реализованное, а не то, что еще предстоит реализовать :)


 
Германн ©   (2010-01-01 02:47) [13]


> Rouse_ ©   (01.01.10 02:36) [12]
>
>

Хакер всегда и везде хакер! Даже почти в 3 ночи 1-го января. :)


 
Rouse_ ©   (2010-01-01 02:51) [14]

Ну у меня есть уважительная причина - я отлаживаю собственнописанный отладчик :) После шампанского это очень даже занимательное занятие :)


 
Германн ©   (2010-01-01 03:29) [15]


> После шампанского это очень даже занимательное занятие :
> )

Ни разу не пробовал.
А до следующего раза ещё
355 дней :(

P.S. После водки пробовал, но то были обычные будни.


 
Сергей М. ©   (2010-01-01 19:27) [16]


> И все дела


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


 
Anatoly Podgoretsky ©   (2010-01-01 20:11) [17]


> tipman ©   (29.12.09 11:51)  

Задачу огласи, а не свое представление.


 
Юрий Зотов ©   (2010-01-02 14:22) [18]

> Сергей М. ©   (01.01.10 19:27) [16]

> Есть факт обnilения какой-то там переменной, а где факт
> завершения работы поточной ф-ции?
> Нет его.
> Даже после новогодней стопки)

Есть факт обnilения переменной В ОБРАБОТЧИКЕ, ВЫЗЫВАЕМОМ ПРИ ЗАВЕРШЕНИИ работы поточной ф-ции.

Даже после новогодней стопки.


 
Сергей М. ©   (2010-01-02 19:35) [19]


> Юрий Зотов ©   (02.01.10 14:22) [18]


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

Единственным достоверным фактом завершения работы поточной функции является факт сигнала объекта синхронизации - хендла этого потока.


 
Юрий Зотов ©   (2010-01-03 13:03) [20]

> Сергей М. ©   (02.01.10 19:35) [19]

> "при завершении", согласись, не означает факт ее (поточной функции)
> завершения

Не соглашусь. Именно это и означает.

> ибо обработчик вызывается именно в ее контексте.

Обработчик события OnTerminate вызывается в контексте главного потока.

========================================

Даже спорить не о чем:

Write an OnTerminate event handler to execute code after the thread finishes executing. The OnTerminate event handler is called in the context of the main thread, which means methods and properties can be called freely.


 
Anatoly Podgoretsky ©   (2010-01-03 13:13) [21]

> Юрий Зотов  (03.01.2010 13:03:20)  [20]

Полностью согласен, завершение работы потока происходит после выхода из метода Execute, после которого только смерть, с оповещением родственников (OnTerminate)


 
Сергей М. ©   (2010-01-03 20:40) [22]


> Юрий Зотов ©   (03.01.10 13:03) [20]


> Обработчик события OnTerminate вызывается в контексте главного
> потока


Тем более.
А дополнительный в это время жив-здоров и ждет возврата из этого обработчика.


> Именно это и означает.


Да нихрена не означает.

Execute - это не поточная функция.
Поточная функция - это функция Classes.ThreadProc.
И завершается она вовсе не при вызове DoTerminate, а при вызове EndThread(). который следует после DoTerminate.


> OnTerminate event handler to execute code after the thread
> finishes executing


finishes - это не finished.

И вызов этого обработчика означает всего лишь факт завершения (штатного или по исключению) выполнения метода Execute, но никак не завершение выполнения поточной фунукии.


 
Юрий Зотов ©   (2010-01-03 21:49) [23]

> И вызов этого обработчика означает всего лишь факт завершения
> (штатного или по исключению) выполнения метода Execute,

Что человеку и требовалось. И больше ему не требовалось ни-че-го.

И не нужно заниматься "двоичным программизьмом". Я ведь тоже могу им заняться и заявить, что задача нерешаема в принципе - и буду прав. Даже уведомлением главного потока из последнего оператора поточной функции. Даже через WaitForЧтоУгодно.

В принципе - не решаема никак. Однако, это не мешает нам писать реально работающие программы?


 
Сергей М. ©   (2010-01-04 21:42) [24]


> Что человеку и требовалось. И больше ему не требовалось
> ни-че-го


Когда грабли непонимания этой важной разницы хлобыстнут автора - в этом, Юрий, будет и твоя "заслуга")


 
Юрий Зотов ©   (2010-01-04 21:47) [25]

> Сергей М. ©   (04.01.10 21:42) [24]

До тех пор, пока он работает в рамках TThread - не хлобыстнут, об этом позаботились разработчики VCL. А когда ему эти рамки станут тесноваты, то он уже и сам сможет писать код без граблей.


 
Сергей М. ©   (2010-01-04 22:17) [26]


> Юрий Зотов ©   (04.01.10 21:47) [25]



> пока он работает в рамках TThread - не хлобыстнут, об этом
> позаботились разработчики VCL


Хлобыстнут, и еще как.
И именно потому, что об этом позаботились разработчики VCL, сделав деструктор Destroy виртуальным.
Достаточно его перекрыть в TThread, беззаботно напичкав тело перекрытого метода разного рода "сложностями", оставив при этом FreeOnTerminate=True - и вот уже между завершением обработчика OnTerminate и фактическим завершением поточной функции вырастает опасная пропасть времени.


 
Юрий Зотов ©   (2010-01-05 00:14) [27]

Вырастает. И что? Ничего страшного.

Вот завершающий кусок поточной функции:

FreeThread := Thread.FFreeOnTerminate;
Result := Thread.FReturnValue;
Thread.DoTerminate;
// Здесь обработчик OnTerminate уже отработал.
Thread.FFinished := True;
SignalSyncEvent;
if FreeThread then
 Thread.Free; // Пусть деструктор работает хоть полчаса. Что страшного?
EndThread(Result);


 
Германн ©   (2010-01-05 02:11) [28]


> Сергей М. ©


> Юрий Зотов ©

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


> На данный момент есть переменная, которая в create потока
> устанавливается в true, в конце Execute, ну или OnTerminate
> она ставится в false. Думал если он завершается и должен
> сам разрушаться, попробвать проверить на nil - не тут то
> было, дескриптор не очищается.


 
Anatoly Podgoretsky ©   (2010-01-05 15:13) [29]

> Германн  (05.01.2010 02:11:28)  [28]

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


 
Сергей М. ©   (2010-01-05 18:08) [30]


> Юрий Зотов ©   (05.01.10 00:14) [27]


> Пусть деструктор работает хоть полчаса. Что страшного?


Ну как что ?
Мало ли какая задача у автора ..
В эти полчаса автор, к примеру, запросто может ничтоже сумняшеся попытаться понасоздавать еще кучу тредов и/или поназанимать еще кучу ресурсов .. или обратиться к ресурсам того самого потока ..
Он же, получив тот самый nil, при этом свято уверует в то что поток действительно завершился).. А поток-то жив-здоров и, возможно, выполняет в это время некие важные действия в перекрытом деструкторе..


> Германн ©   (05.01.10 02:11) [28]


Серега, мы тут с Юрием последний огурец режем)
Мож оно кому и поможет кроме автора)


 
Демо ©   (2010-01-05 18:31) [31]


> tipman ©   (29.12.09 11:51) 


Проверять при необходимости либо WaitFor(ThreadHandle,0),
Либо в самом экземпляре TThread обнулять переменную, ссылающуюся на этот объект, и при необходимости проверять.


 
Anatoly Podgoretsky ©   (2010-01-05 18:41) [32]

> Сергей М.  (05.01.2010 18:08:30)  [30]

Значит вы скоро узнаете о завершение


 
Сергей М. ©   (2010-01-05 21:22) [33]


> вы скоро узнаете о завершение


Ахинея


 
Anatoly Podgoretsky ©   (2010-01-05 21:55) [34]

> Сергей М.  (05.01.2010 21:22:33)  [33]

Думаешь не скоро?


 
Сергей М. ©   (2010-01-05 22:25) [35]


> Anatoly Podgoretsky ©   (05.01.10 21:55) [34]


Толя, прекрати нести ахинею.


 
oxffff ©   (2010-01-05 23:41) [36]

Друзья, RegisterWaitForSingleObject  в помощь.
Даже после шампанского, огромной пиццы и кучи конфет. :)



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

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

Наверх




Память: 0.54 MB
Время: 0.005 c
15-1261431022
Юрий
2009-12-22 00:30
2010.03.07
С днем рождения ! 22 декабря 2009 вторник


2-1262677121
Андрей Пл
2010-01-05 10:38
2010.03.07
Остановить выполнение пророги в задонном месте до опред. события?


1-1239373349
buzb
2009-04-10 18:22
2010.03.07
Проблема с прозрачностью в Bitmap


15-1260399563
wl
2009-12-10 01:59
2010.03.07
Линукс - зачем?


15-1261561398
vv_fran
2009-12-23 12:43
2010.03.07
Нагрузка на проц от Delphi 7 в Win2003 Server





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский