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

Вниз

TThread + TTimer   Найти похожие ветки 

 
vecna ©   (2005-08-30 16:47) [0]

Че-та мне снова пора в отпуск...
Можно ли успользовать в потоках TTimer? С одной стороны он реализуется APIфункциями, с другой он наследник TComponent и это вызывает сомнения.


 
Erik1 ©   (2005-08-30 17:03) [1]

Нет, поскольку используется механизм сообщений. Для этого надо использовать спецальный таймер. http://www.delphikingdom.com/asp/viewitem.asp?catalogid=434


 
Суслик ©   (2005-08-30 17:10) [2]

Можно, если обрабатывать сообщения самому.

Типа такого (за точность и правильность не ручаюсь, но работает)

type
  TMyThread = class(TThread)
     procedure Execute(); override;
     procedure fOnTimer(Sender: TObject);
     procedure fDoSomething();
  end;

procedure TMyThread.Execute();
var
  kTimer: TTimer;
  kMsg: TMsg;
begin
  kTimer := TTimer.Create(nil);
  try
     kTimer.OnTimer := fOnTimer;
     kTimer.Interval := 1000;
     kTimer.Enabled := True;
     while true do
        if GetMessage(kMsg, 0, 0, 0) then
        begin
           TranslateMessage(kMsg);
           DispatchMessage(kMsg);
        end;
  finally
     kTimer.Free();
  end;
end;

procedure TMyThread.fOnTimer(Sender: TObject);
begin
  Synchronize(fDoSomething);
end;

procedure TMyThread.fDoSomething();
begin
  Form1.Memo1.Lines.Add("a");
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  TMyThread.Create(False);
end;


 
Reindeer Moss Eater ©   (2005-08-30 17:14) [3]

И что же будет делать поток, ожидая очередного тика таймера?
Крутить тупой пустой цикл?

Зачем тогда вообще таймер, если тупой цикл крутится и без него?
:)


 
Суслик ©   (2005-08-30 17:15) [4]


>  [3] Reindeer Moss Eater ©   (30.08.05 17:14)

согласен :)
но на вопрос мой пост вроде отвечает


 
Lamer@fools.ua ©   (2005-08-30 17:15) [5]

Я бы
while true do
заменил на
while not Terminated do


 
Суслик ©   (2005-08-30 17:16) [6]


>  [5] Lamer@fools.ua ©   (30.08.05 17:15)

да это тест, я его за 1.5 минуты написал с отладкой: true - короче


 
vecna ©   (2005-08-30 17:19) [7]

2Суслик
Ага, спасибо, попробую

2Reindeer Moss Eater
Нужно уметь парктически сразу определять, что Terminated = true.


 
Суслик ©   (2005-08-30 17:19) [8]

А зачем в потоке может понадобиться таймер вообще?


 
Reindeer Moss Eater ©   (2005-08-30 17:25) [9]

Вот именно.
Таймер-то зачем?


 
Digitman ©   (2005-08-30 17:43) [10]


> Нужно уметь парктически сразу определять, что Terminated
> = true


и что этому мешает ?
и как этому может помочь таймер, если код обработки его "тика" будет выполнен не иначе как в том же трэде, который у тебя в момент "тика" занят какими-то иными длительнымы вычислениями ?

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


 
Leonid Troyanovsky ©   (2005-08-31 08:57) [11]


> Reindeer Moss Eater ©   (30.08.05 17:14) [3]
> И что же будет делать поток, ожидая очередного тика таймера?
> Крутить тупой пустой цикл?


Ждать сообщений - GetMessage.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2005-08-31 09:13) [12]


> Суслик ©   (30.08.05 17:10) [2]
..
>   kTimer := TTimer.Create(nil);
..
>      while true do
>         if GetMessage(kMsg, 0, 0, 0) then
>         begin
>            TranslateMessage(kMsg);
>            DispatchMessage(kMsg);


Про true уже говорили, т.е., лучше while GetMessage do.
Кроме того, для такого потока лучше сделать свой Terminate,
который пошлет потоку WM_QUIT. Ну, и, наверное, свой
Free, т.к. Terminate - статический.
Стоит также отметить, что сам TTimer создает окно верхнего
уровня, что такому потоку никчему.
Т.е., можно просто


procedure TimerFunc(hwnd:HWND; msg: UINT; idEvent:UINT; dwTime: DWord); stdcall;
begin
 ..
end;

var
 msg: TMsg;

begin
 SetTimer(0, 0, 1000, @TimerFunc);
 while GetMessage(msg, 0, 0, 0) do
   DispatchMessage(msg);
end.


--
Regards, LVT.


 
Reindeer Moss Eater ©   (2005-08-31 09:22) [13]

>Ждать сообщений - GetMessage.
Круто. А без таймера ему конечно ждать скучно будет.


 
Leonid Troyanovsky ©   (2005-08-31 09:36) [14]


> Reindeer Moss Eater ©   (31.08.05 09:22) [13]
> >Ждать сообщений - GetMessage.
> Круто. А без таймера ему конечно ждать скучно будет.


Я ответил, что он будет делать, ожидая сообщения таймера.
Просто ждать. Скучно ему будет или нет, мне пофиг.

--
Regards, LVT.


 
Reindeer Moss Eater ©   (2005-08-31 09:48) [15]

Вопрос бы в том, что будет делать поток, ожидая тика.
Что бы ждать тика поток должен крутить цикл, в котором конечно он может еще и ждать сообщений и обрабатывать их.
То есть в любом случае необходим цикл.
Отсюда и вытекает второй вопрос: а таймер-то зачем здесь приплетать?


 
Leonid Troyanovsky ©   (2005-08-31 10:12) [16]


> Reindeer Moss Eater ©   (31.08.05 09:48) [15]
> Вопрос бы в том, что будет делать поток, ожидая тика.
> Что бы ждать тика поток должен крутить цикл, в котором конечно
> он может еще и ждать сообщений и обрабатывать их.
> То есть в любом случае необходим цикл.


RTFM: GetMessage.
А лучше почитать Рихтера, про потоки и их очереди.
И про то, что такое спящие потоки.


> Отсюда и вытекает второй вопрос: а таймер-то зачем здесь
> приплетать?


Этот вопрос, видимо, не ко мне.

--
Regards, LVT.


 
Reindeer Moss Eater ©   (2005-08-31 10:55) [17]

В любом случае в потоке будет цикл, либо поток будет использовать функцию ожидания (опять же в цикле)
Поэтому таймер там - не нужен вовсе.


 
Alexander Panov ©   (2005-08-31 10:57) [18]

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


 
Alexander Panov ©   (2005-08-31 11:00) [19]

Reindeer Moss Eater ©   (31.08.05 10:55) [17]
Поэтому таймер там - не нужен вовсе.


ну почему же - SetTimer - нормальный вариант.


 
Игорь Шевченко ©   (2005-08-31 11:09) [20]

Я бы WaitableTimer использовал или TimerQueue, ни с какими окнами не связано.

По поводу того, зачем нужен таймер в потоке - периодически что-то опрашивать, например, не нагружая основной поток. Аська, например, опрашивает что-то периодически, не мешая набирать сообщение...


 
Digitman ©   (2005-08-31 11:18) [21]


> Alexander Panov


"ключевой" момент всей этой затеи (цитирую автора):


> vecna ©   (30.08.05 17:19) [7]
> Нужно уметь парктически сразу определять, что Terminated
> = true.


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

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


 
Digitman ©   (2005-08-31 11:31) [22]


> Игорь Шевченко ©   (31.08.05 11:09) [20]


пока трэд работает в user time, толку от таймера, сам понимаешь, нет никакого - для обнаружения и обработки "тика" таймера трэд как правило должен переключиться в kernel time .. для немедленной реакции на "тик" это переключение требуется выполнять насколько это возможно чаще, при этом "полезная деятельность" трэда сводится к нулю, ибо "окон" в user time становится все меньше и меньше ... и нужен ли в конечном итоге такой трэд, который только и делает, что чуть ли не без конца (от "рождения" до "смерти") беспокоится только о том, не сработал ли таймер - это нужно осознать прежде всего автору сабжа ..


 
Суслик ©   (2005-08-31 11:36) [23]


>  [12] Leonid Troyanovsky ©   (31.08.05 09:13)
> Про true уже говорили, т.е., лучше while GetMessage do.


ну это типа "быстрый" пример, не претендующих на законченность.


> Кроме того, для такого потока лучше сделать свой Terminate,
> который пошлет потоку WM_QUIT.


Это я понимаю зачем - иначе не прервется ожидание getmessage и все "зависнет".


> Ну, и, наверное, свой
> Free, т.к. Terminate - статический.


А вот этого не понимаю? Это про что?

-----------
За поправки про окно спасибо, интересно было почитать.


 
Игорь Шевченко ©   (2005-08-31 11:51) [24]

Digitman ©   (31.08.05 11:31) [22]


> для обнаружения и обработки "тика" таймера трэд как правило
> должен переключиться в kernel time


Вах! Зачем переключаться ? в SetWaitableTimer указываешь, какую процедуру надо вызывать при достижении нужного интервала, например.

hint: вызовы для получения и обработки сообщений тоже в режиме ядра выполняются, так что профит несущественный :)


 
Digitman ©   (2005-08-31 11:58) [25]


> Игорь Шевченко ©   (31.08.05 11:51) [24]


Все бы было расчудесно, Игорь, если бы не ма-а-аленькая "загвозка":

If you call SetWaitableTimer and the thread is not in an alertable state, the completion routine is canceled

так что, один черт, придется как можно чаще переводить трэд в тревожное состояние, хотя бы на мизерные промежутки времени ..

шило на мыло, ч.н.)


 
Игорь Шевченко ©   (2005-08-31 12:08) [26]

Digitman ©   (31.08.05 11:58) [25]

Не совсем шило на мыло. Тебе не надо делать окон, обрабатывать у них WM_TIMER и т.п.

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


 
Digitman ©   (2005-08-31 12:38) [27]


> Игорь Шевченко ©   (31.08.05 12:08) [26]


> Не совсем шило на мыло. Тебе не надо делать окон, обрабатывать
> у них WM_TIMER и т.п


Об окнах и речи не идет ...
А ожидание WM_TIMER при SetTimer() точно так же как и ожидание колбэка при SetWaitableTimer() требует kernel time, так что никаких явных преимуществ задействования того или иного таймера в таком абстрактном изложении автором задачи я не вижу


> В этой концепции предполагается, что поток не будет активно
> заниматься какой-то другой активной деятельностью помимо
> работы с таймером


В том-то и дело, что эта концепция вроде бы противоречит авторскому видению решения ...
Ему ведь нужно что ? Ему, как пока видно из его постов, нужно следующее : запустить какой-то там таймер (который будет отсчитывать некие предельно малые интервалы времени) и спокойно продолжать делать в трэде свои "дела", не задумываясь ни о каких "режимах ядра", "тревожных состояниях", "ожиданиях" и прочей непонятной и потому якобы несущественной лабуде ..
Мол, когда таймер тикнет, то выполнение некоего основного алгоритма трэда само по себе (!) прервется и при этом будет вызвана некая п/программа, где первым делом будет осуществляться проверка флага Terminated на предмет не закруглиться ли немедленно этому трэду "по хозяйству"..


 
Leonid Troyanovsky ©   (2005-08-31 12:48) [28]


> Суслик ©   (31.08.05 11:36) [23]

> > Ну, и, наверное, свой
> > Free, т.к. Terminate - статический.

> А вот этого не понимаю? Это про что?


В реализации Destroy можно увидеть Terminate, однако,
т.к. Terminate не виртуальный, то вызван будет он,
а не новая его реализация.

Т.е., если кто-то привык к тому, что Free остановит поток,
то должен озаботится и своим деструктором,
который вызовет нужный Terminate.

--
Regards, LVT.


 
Суслик ©   (2005-08-31 12:51) [29]


>  [28] Leonid Troyanovsky ©   (31.08.05 12:48)

тогда не "свой free", а "свой destroy". Так?
Тогда понял.


 
Leonid Troyanovsky ©   (2005-08-31 13:05) [30]


> Суслик ©   (31.08.05 12:51) [29]

> тогда не "свой free", а "свой destroy". Так?


Конечно.
Хорошо, что хоть деструкторы виртуальны :)

--
Regards, LVT.


 
Игорь Шевченко ©   (2005-08-31 13:48) [31]

Digitman ©   (31.08.05 12:38) [27]


> Об окнах и речи не идет ...


Согласен, об окнах речь не идет. Но о цикле выборки сообщений, в любом случае, речь идет. Которая выборка сообщений тоже обращается к ядру.


> так что никаких явных преимуществ задействования того или
> иного таймера в таком абстрактном изложении автором задачи
> я не вижу


Автор задачу изложил на совсем уж высоком уровне абстрации, я из его объяснения задачи не понял вообще.
Я вижу то преимущество, что не надо организовывать выборку сообщений.


 
Digitman ©   (2005-08-31 14:19) [32]


> Игорь Шевченко ©   (31.08.05 13:48) [31]


ну ладно, что там бестолку рассуждать ...

"вот предет барин - барин нас рассудит")



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

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

Наверх





Память: 0.54 MB
Время: 0.054 c
3-1123694565
Aleksandr.
2005-08-10 21:22
2005.09.25
Как снять ReadOnly с поля TADOQuery?


4-1123025533
i-s-v
2005-08-03 03:32
2005.09.25
Несколько вопросов по WinAPI


14-1125152413
Гоман
2005-08-27 18:20
2005.09.25
Вопрос про дефективный монитор


14-1125345851
KilkennyCat
2005-08-30 00:04
2005.09.25
30 августа. С днем рождения!


1-1125568760
ssmaxx
2005-09-01 13:59
2005.09.25
Ошибка #36 при работе с jpeg





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