Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Потоки [D7, WinXP]


Страницы:   1 2

Ypbi4 ©   (2007-10-30 08:11:00) 

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


Ypbi4   (2007-10-30 12:16:00) [1]

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


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


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


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


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


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


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


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


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

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


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


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


Не важно.

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


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


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

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


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


> сделал так


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

Аминь.


Ypbi4   (2007-10-30 11:05:00) [8]

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

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


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

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;


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

> 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:23:00) [11]

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

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


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

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


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

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


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

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

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


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


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


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

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


Ypbi4   (2007-10-30 09:11:00) [16]

Исправил :)
сделал так -
В главной форме в 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:03:00) [17]


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


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


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

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

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

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


MBo   (2007-10-30 08:54:00) [19]

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

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


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


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


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


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо