P.S.
An important exception is that threads at the highest priority level (level 0, THREAD_PRIORITY_TIME_CRITICAL) do not share the time slice with other threads at the highest priority level. These threads continue executing until they have finished.
Нужно воткнуть бесконечный цикл, в котором шел бы непрерывный опрос, ну, скажем, значения некоторой переменной. Как мне это сделать корректно?
Проблема даже не в том, что если это делать в лоб, я не смогу обрабатывать
остальные сообщения из своей программы, а в том, что когда в программе
такой цикл запускается, все остальные приложения зависают до тех пор, пока задача не будет убита.
[Win32] все проще13.06.01 22:14 Автор: kabanchik Статус: Незарегистрированный пользователь
"прикрепи" к своему объекту Event, запусти поток(и), как ребята уже сказали, поставь его (их) в состояние ожидания.
когда данные объекта изменяться ставит Event в состояние signaled.
поток(и) заитересованные в нем получат уведомление, возобновит(ят) работу и просмотрят данные, а до этого смысла нет в холостую крутиться и захватывать процессорное время.
sleep(timeout) в цикле и не парить голову :)13.06.01 19:26 Автор: XR <eXtremal Research> Статус: The Elderman
такого времени опроса (гарантированного) тебе не даст сделать шедулер Win - меняй OS на чего нибудь RT14.06.01 13:57 Автор: XR <eXtremal Research> Статус: The Elderman
Гарантированное время опроса в Win32 можно получить только на уровне драйверов устройств (тех самых, которые никто не любит писать), для этого они и созданы.
Если надо приблизится к гарантированному времени - тогда можно потоку дать приоритет real-time (только надо разобраться с абсолютными и относительными приоритетами - RTFM). В принципе, должно работать быстро, но не гарантировано - твой процесс, например, могут выпихнуть в своп, и тогда дополнительное время уйдет на подгрузку. Я всего этого не пробовал, поэтому больше предполагать не буду. Если чего получится - опубликуй.
А чтоб протестить можешь просто своему процессу поставить real-time в таск манагере (НТ) - если все не умрет, значит написал правильно.
[Win32] Можно и не менять15.06.01 09:54 Автор: cb <cb> Статус: Member
> Гарантированное время опроса в Win32 можно получить только > на уровне драйверов устройств (тех самых, которые никто не > любит писать), для этого они и созданы.
ну я бы не сказал что они сделаны "именно для ЭТОГО"...
даже в драйвере (речь про WinNT/Win2k) тебе никто ничего не гарантирует.
существуюс спец. навески на NT которые максимально приближают эту ось
к real-time системам, но все эти вещи по сути представляют из себя ось в оси и никак не завязаны даже на ядро NT не говоря уже о UserMode.
Вот тут Q94265 посмотри. Я не проверял этих самых good real-time capabilities, но видел real-time системы с урезанным (но без всяких навесок) НТ.15.06.01 18:06 Автор: prop Статус: Незарегистрированный пользователь
> > Гарантированное время опроса в Win32 можно получить > только > > на уровне драйверов устройств (тех самых, которые > никто не > > любит писать), для этого они и созданы. > > ну я бы не сказал что они сделаны "именно для ЭТОГО"... > даже в драйвере (речь про WinNT/Win2k) тебе никто ничего не > гарантирует. > существуюс спец. навески на NT которые максимально > приближают эту ось > к real-time системам, но все эти вещи по сути представляют > из себя ось в оси и никак не завязаны даже на ядро NT не > говоря уже о UserMode.
Можно и не менять14.06.01 15:52 Автор: XR <eXtremal Research> Статус: The Elderman
> Если надо приблизится к гарантированному времени - тогда > можно потоку дать приоритет real-time (только надо > разобраться с абсолютными и относительными приоритетами - > RTFM). В принципе, должно работать быстро, но не > гарантировано - твой процесс, например, могут выпихнуть в > своп, и тогда дополнительное время уйдет на подгрузку. Я > всего этого не пробовал, поэтому больше предполагать не > буду. Если чего получится - опубликуй.
Есть как минимум 2 НО:
1) REALTIME_PRIORITY_CLASS доступен тилько группе администраторов
2) Есть очень ненулевая вероятность залочить систему насмерть RT процессом
потому как большая часть системы работает с более низким классом приоритета
(не спасет даже комбинация из 3-х пальцев :))
> А чтоб протестить можешь просто своему процессу поставить > real-time в таск манагере (НТ) - если все не умрет, значит > написал правильно.
Это обычно называется "отладка методом русской рулетки" :)))
Нее, это "отладка методом научного тыка" :))14.06.01 16:45 Автор: prop Статус: Незарегистрированный пользователь
> > Если надо приблизится к гарантированному времени - > тогда > > можно потоку дать приоритет real-time (только надо > > разобраться с абсолютными и относительными > приоритетами - > > RTFM). В принципе, должно работать быстро, но не > > гарантировано - твой процесс, например, могут > выпихнуть в > > своп, и тогда дополнительное время уйдет на подгрузку. > Я > > всего этого не пробовал, поэтому больше предполагать > не > > буду. Если чего получится - опубликуй. > > Есть как минимум 2 НО: > > 1) REALTIME_PRIORITY_CLASS доступен тилько группе > администраторов > 2) Есть очень ненулевая вероятность залочить систему > насмерть RT процессом > потому как большая часть системы работает с более низким > классом приоритета > (не спасет даже комбинация из 3-х пальцев :)) > > > > А чтоб протестить можешь просто своему процессу > поставить > > real-time в таск манагере (НТ) - если все не умрет, > значит > > написал правильно. > > Это обычно называется "отладка методом русской рулетки" > :)))
Так вот, тыкал я тыкал... =)15.06.01 10:08 Автор: Xan Статус: Незарегистрированный пользователь
Так все же я не понял. Объясните мне тупому. Если я не собираюсь генерировать сообщения каждую милисекунду, а всего лишь хочу крутить свой цикл так быстро, как только получиться, неужели ось не даст мне это сделать быстрее, чем тысячу раз в секунду. И еще про шедуллер я не совсем понял, причем сдесь он.
Спасибо, кто прочел.
> Так все же я не понял. Объясните мне тупому. Если я не > собираюсь генерировать сообщения каждую милисекунду, а > всего лишь хочу крутить свой цикл так быстро, как только > получиться, неужели ось не даст мне это сделать быстрее, > чем тысячу раз в секунду. Даст. Но если будет более приоритетный поток (все потоки ядра более приоритетны чем пользовательские), и он будет что-нибудь делать, то ты своего кванта не получишь, пока он не освободится.
И еще про шедуллер я не совсем
> понял, причем сдесь он. Смотря какой. Task Scheduer сервис занимается совсем другим и здесь нипричем. Но где-то в ядре есть нечто очеь приоритетное, что управляет переключением потоков - если назвать его шедулером, то он причем. Как называет его микрософт я не знаю.
> Спасибо, кто прочел. Всегда пожста.
Совет дня:
Если пишешь коммерческую прогу, которая должна гарантированно работать на любой машине, надо изучать DDK. Гарании по быстродействию есть только в нулевом кольце.
Если надо решить локальную задачу по управлению любимой кофеваркой или электрочайником то разберись с потоками и приоритетами. А потом поубивай все ненужные сервисы и задачи на машине - включая explorer. Если есть два процессора, поставь свою задачу на один, а все остальное - на другой. (Affinity Mask). Правда с ядром такие штуки не пройдут.
Чем быстрее машина, тем быстрее крутится твой цикл. Если машина больше ни хрена не делает - значит и задержек нет. (если возникла задержка - значит плохо предохранялись :)).
> BOOL fRetVal = TRUE; > while(!fTimeout) // Тут глобальный флаг > { > memset(&lpMsg,0,sizeof lpMsg); // убираем предыдущее > PeekMessage(&lpMsg, 0, 0, 0, PM_REMOVE); > if (lpMsg.message == WM_QUIT) > fRetVal = FALSE, break; > > TranslateMessage(&lpMsg); > DispatchMessage(&lpMsg); > if(MYREGISTER) MYHANDLER(); // Во, наш полинг! > } > ... > return fRetVal; > > Так все же я не понял. Объясните мне тупому. Если я не > собираюсь генерировать сообщения каждую милисекунду, а > всего лишь хочу крутить свой цикл так быстро, как только > получиться, неужели ось не даст мне это сделать быстрее, > чем тысячу раз в секунду.
при большой загрузке не даст - отчего и говорить про гарантии не приходится ...
...тем более с вышеприведенным кодом, завязанным на очередь сообщений...
И еще про шедуллер я не совсем
> понял, причем сдесь он.
он здесь при том что стратегия планирования в NT не ориентирована на ГАРАНТИРОВАННОЕ время отклика ...
BTW: вообще то планировщик NT вещь довольно темная :)
PS: кстати никто не напомнит величину стандартного таймслайса для NT ?
> Спасибо, кто прочел.
[Win32] Сори, мессага здесь.15.06.01 17:00 Автор: cb <cb> Статус: Member
P.S.
An important exception is that threads at the highest priority level (level 0, THREAD_PRIORITY_TIME_CRITICAL) do not share the time slice with other threads at the highest priority level. These threads continue executing until they have finished.
[Win32] Как мне грамотно организовать полинг в WinApplication?13.06.01 17:56 Автор: prop Статус: Незарегистрированный пользователь
Если WinApplication=Win32Application, то грамотно такие вещи делаются в отдельном потоке. Создаешь поток, ставишь ему приоритет - и вперед.
Если ты дельфируешь, то там есть готовый объект - TThread, очень удобный.
Если лень связываться с потоками сделай по таймеру - самое часте раз в миллисекунду.
В обоих случаях ничего не повисает.
Если первые два способа не подходят, и ты опять же дельфируешь, то в своем бесконечном цикле каждый раз после проверки вызывай Application.ProcessMessages - ничего не повиснет, все формы будут перерисовываться, можешь даже нажатия клавиш получать.
OK. А если под 'чистым' API, то как мне Application.ProcessMessages имитировать13.06.01 18:41 Автор: Xan Статус: Незарегистрированный пользователь
> Если WinApplication=Win32Application, то грамотно такие > вещи делаются в отдельном потоке. Создаешь поток, ставишь > ему приоритет - и вперед. > Если ты дельфируешь, то там есть готовый объект - TThread, > очень удобный. > Если лень связываться с потоками сделай по таймеру - самое > часте раз в миллисекунду. > В обоих случаях ничего не повисает. > Если первые два способа не подходят, и ты опять же > дельфируешь, то в своем бесконечном цикле каждый раз после > проверки вызывай Application.ProcessMessages - ничего не > повиснет, все формы будут перерисовываться, можешь даже > нажатия клавиш получать.
Примерно так14.06.01 12:43 Автор: prop Статус: Незарегистрированный пользователь
Это из исходников Дельфей. Просто вызывается PeekMessage.
Хинт - то что начинается на F - это приватные переменные класса TApplication - можно похерить.
procedure TApplication.ProcessMessages;
var
Msg: TMsg;
begin
while ProcessMessage(Msg) do;
end;
function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
Handled: Boolean;
begin
Result := False;
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
else
FTerminate := True;
end;
end;