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

Вниз

Потоки   Найти похожие ветки 

 
Ypbi4 ©   (2007-10-30 08:11) [0]

Ситуация следующая -
По таймеру через определенный промежуток времени запускаю поток, по окончании операций он убивается. Подскажите plz, как узнать запущен ли поток? (Suspended не пойдет, т.к. поток убивается и получить его свойства нельзя)


 
MBo ©   (2007-10-30 08:22) [1]

при завершении потока инициировать событие OnTerminate


 
Сергей М. ©   (2007-10-30 08:25) [2]


> как узнать запущен ли поток?


Если ты его успешно "запустил", то значит он "запущен", что тут еще узнавать ?


> по окончании операций он убивается


Кем ?


 
Ypbi4 ©   (2007-10-30 08:43) [3]

При запуске потока прописываю свойство
cl.FreeOnTerminate:=true - по окончании процесса он самоуничтожится.
cl - имя потока

сделал проверку так
if cl <> nil then statusbar1.panels[1].text:="поток в работе" else
 Begin
   cl:=TScan.Create(true);
   cl.Resume;
   cl.Priority:=tpLower;
   cl.FreeOnTerminate:=true; //прописывал так же свойство и в классе потока
   statusbar1.panels[1].text:="поток запущен";
 end;

Теперь он первый раз запускается, если ранее не был запущен все выполняет и должен самоуничтожиться, но почему то он при следущей проверки пишет что "поток в работе", т.е. cl<>nil, хотя поток на самом деле не запущен.. :(


 
Сергей М. ©   (2007-10-30 08:53) [4]


> cl<>nil, хотя поток на самом деле не запущен


Для того чтобы cl стала равна nil, нужно соответствующее присвоение.
Ты его где-то делаешь ? Нет. Ну так а что же тогда хочешь ?)


 
MBo ©   (2007-10-30 08:54) [5]

>следущей проверки пишет что "поток в работе", т.е. cl<>nil,
Так и должно быть - деструктор не зануляет ссылку.

Какая вообще задача стоит?


 
Однокамушкин   (2007-10-30 08:55) [6]

I>
> cl - имя потока

cl - это не "имя потока", это указатель на объект типа TThread (точнее, его наследника), который реализует нить... И ни нить, ни объект TThread ничего не знает об этом указателе, поэтому не обнуляет . Тут Юрий Зотов недавно очень хорошую аналогию приводил: указатель на объект - это что-то вроде телефона человека, записанного в чьей-то записной книжке, и когда человек умирает, ничего с этими записями не случается, они никуда не исчезают... Поэтому cl не равно nil, даже когда ни нити, ни объекта уже не существует

А MBo ©   (30.10.07 08:22) [1] правильную мысль высказал - назначать OnTerminate и по срабатыванию этого события определять, что нить завершилась


 
Сергей М. ©   (2007-10-30 09:03) [7]


> Однокамушкин   (30.10.07 08:55) [6]


На момент обработки события OnTerminate нить не завершилась, ибо именно нить является инициатором этого события.


 
Ypbi4 ©   (2007-10-30 09:11) [8]

Исправил :)
сделал так -
В главной форме в public ввел переменную nilka:integer;
На событие OnCreate формы nilka:=0;
Затем переписал
if nilka<>0 then statusbar1.panels[1].text:="поток в работе" else
Далее в коде потока в начале операции прописал mainform.nilka:=1;
а в конце mainform.nilka:=0; теперь работает:)
Спасибо за подсказку ;)


 
Сергей М. ©   (2007-10-30 09:23) [9]


> теперь работает


Нет, не работает.

Равество твоей "нилки" нулю вовсе не означает, что потока еще/уже не существует.


 
Ypbi4 ©   (2007-10-30 09:58) [10]

Установил время таймера такое что бы поток не успевал закончиться до следущего OnTimer, (т.е. время выполнения операции ~ 8 сек, опрос установил на 1 сек), все выполнялось...

Ну если не сложно, то подскажите, как все таки проверить запущен ли поток? :)


 
Сергей М. ©   (2007-10-30 10:10) [11]

Объясни, начерта нужен таймер вообще ?


 
Ypbi4 ©   (2007-10-30 10:20) [12]

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


 
Сергей М. ©   (2007-10-30 10:23) [13]

Ну так и реализуй периодический обмен с сервером в самом потоке !

За каким лешим к этому нужно привлекать основной поток и таймер в этом основном потоке ?


 
Юрий Зотов ©   (2007-10-30 10:33) [14]

> Ypbi4 ©   (30.10.07 08:43) [3]

1. Переменную cl сделать полем формы.

2. Ввести метод формы:

procedure TForm1.ThreadFinished(Sender: TObject);
begin
 cl := nil;
 Statusbar1.Panels[1].Text := "Поток завершился"
end;

3. Ввести метод формы:

procedure TForm1.LaunchThread;
begin
 if cl = nil then
 begin
   cl := TScan.Create(True);
   cl.Priority := tpLower;
   cl.FreeOnTerminate := True
   cl.OnTerminate := ThreadFinished;
   cl.Resume;
   Statusbar1.Panels[1].Text := "Поток в работе"
 end
end;

и вызывать этот метод для запуска потока

4. Проверка (если будет нужна):

if cl = nil then
 ... // Поток завершен
else
 ... // Поток работает

Детали см. в справке.


 
Сергей М. ©   (2007-10-30 10:57) [15]

TScan = class(TThread)
..
private
..
 FTimer: TTimer;
 procedure DoOnTimer(Sender: TObject);
..
public
...
 destructor Destroy; override;
...
end;

destructor TScan.Destroy;
begin
 if GetCurrentThreadId <> MainThreadId then
   PostThreadMessage(ThreadId, WM_QUIT, 0, 0);
 inherited;
end;

procedure TScan.DoOnTimer(Sender: TObject);
begin
 .. сеанс обмена с сервером ...
end;

procedure TScan.Execute;
var
 Msg: TMsg;
begin
 Fimer := TTimer.Create;
 try
   FTimer.Interval := ...;
   FTimer.OnTimer := DoTimer;
   FTimer.Active := True;
   while not Terminated and GetMessage(Msg, 0, 0, 0) do
     DispatchMessage(Msg);
 finally
   FTimer.Free;
 end;
end;


 
Ypbi4 ©   (2007-10-30 11:05) [16]

Круть :) мне далеко до вас:)
я сделал так
label
 scan;

Begin
 scan:
   Begin
       <код с подключением к серверу и проверками>
   end;
 sleep(5000);
 goto scan;
end;


 
Сергей М. ©   (2007-10-30 11:07) [17]


> сделал так


Ну сделал и сделал)

Аминь.


 
Однокамушкин   (2007-10-30 11:10) [18]


> Сергей М. ©   (30.10.07 09:03) [7]
> На момент обработки события OnTerminate нить не завершилась,
>  ибо именно нить является инициатором этого события.

Ну и что? Выполнение Execute уже закончилось, нить гарантированно завершится, и если у неё стоит FreeOnTerminate, можно вообще забыть о её существовании, т.е. обнулить переменную cl, а если из-за этого новая нить будет создана чуть раньше, чем уничтожится старая, ничего страшного уже не произойдёт, т.к. старая будет выполнять только чисто служебный код


 
Сергей М. ©   (2007-10-30 11:21) [19]


> нить гарантированно завершится


Не важно.

Условие автора - в каждый момент времени должен существовать не более чем один поток (именно как ОС-объект - см. термин "запущен").


 
Однокамушкин   (2007-10-30 12:02) [20]


> Сергей М. ©   (30.10.07 11:21) [19]

Не думаю, что автора стоит понимать так буквально, учитывая, что он ещё немного "плавает" в терминологии и не отличает нить от объекта... Думаю, ему было бы вполне достаточно, чтобы следующая активация Execute не запускалась бы до того, как завершится предыдущая


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


> Однокамушкин   (30.10.07 12:02) [20]


Подозреваю, что и таймер-то ему нафих не нужен)


 
Сергей М. ©   (2007-10-30 12:07) [22]


> Однокамушкин   (30.10.07 12:02) [20]
>
>


Да и не помешает четкое понимание термина "запущенности" нити.


 
Ypbi4 ©   (2007-10-30 12:16) [23]

Таймер как раз и нужен :) Сервак не локальный, т.е. в инете, -> уменьшить трафик, т.к. большинство данных повторяются (например у мну работает с snpp и постоянно проверяется статус сообщений доставлено или нет). При чем, не всегда нужны свежие данные, т.е. делать проверку через 5 часов или раз в сутки (опять же экономим трафик), Т.е. это оправдано.
Юрий Зотов ©   (30.10.07 10:33) [14] - спасибо :)



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

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

Наверх




Память: 0.53 MB
Время: 0.019 c
15-1192876882
SerJaNT
2007-10-20 14:41
2007.11.25
Опять HTML


2-1193965529
ореол
2007-11-02 04:05
2007.11.25
Загрузка содержимого *.doc файла в своем приложении


15-1192817453
Ekzot
2007-10-19 22:10
2007.11.25
Где IE хранит иконки кнопок навигации.


2-1194006557
timekiller
2007-11-02 15:29
2007.11.25
Прокрутка формы


2-1193848611
harisma
2007-10-31 19:36
2007.11.25
Позиционирование на запись в ComboBox