![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Здадержка [D5, Win95/98]
Snake2000 © (2001-12-21 17:28:00)Как реализовать задержку, что бы при выполнении цикла можно было свободно работать с моим приложением? Конструкция типа
for i:=1 to 1000 do
begin
......
sleep(1);
Application.Processmessages;
end;
не подходит (ну это и глупое решение - сами понимаете :)), т.к. все равно до завершения цикла, с окном работать невозможно.
Помогите!
Юрий Зотов (2001-12-24 12:37:00) [1]> panov © (22.12.01 11:31)
> А во время Application.ProcessMessages процессор
> как я понимаю занят на полную катушку...
Смотрим в исходники...
procedure TApplication.ProcessMessages;
var
Msg: TMsg;
begin
while ProcessMessage(Msg) do {loop};
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;
... // Skipped (обработка выбранного из очереди сообщения)
end;
end;
Таким образом, вызов Application.ProcessMessages всего лишь приводит к обработке всех находящихся в очереди на данный момент сообщений. При этом, конечно, процессор занят (а как иначе можно их обработать?). Если же сообщений в очереди нет, то тут же происходит возврат.
Таким образом, вызов Application.ProcessMessages нагружает процессор не более, чем обычно. Что и естественно, поскольку все GUI-программы именно так и работают - постоянно крутят цикл выборки сообщений. И ничего страшного при этом не происходит.
Тут важно вот что. Нам требуется выполнить некие действия и обработать сообщения. Для этого мы делаем цикл:
while <условие> do
begin
... // Выполняем действия
Application.ProcessMessage // Обрабатываем сообщения
end;
Насколько при этом будет загружен процессор? Ответ - всегда на 100% (а как же иначе? по-другому он работать не умеет), но только В ПРЕДЕЛАХ ОДНОГО КВАНТА. По истечении же этого кванта CPU получит другой процесс. И если период измерения загрузки CPU более одного кванта (а оно, надо полагать, так и есть, иначе это не измерение а бред получится), то СРЕДНЯЯ за этот период загрузка CPU может оказаться менее 100% (конкретная цифра зависит от всех процессов в системе).
И ничего страшного в этом нет. Нам требуется сделать определенную работу. Если для ее выполнения требуется 100%-ная загрузка CPU, значит, она будет 100% - хоть выноси эту работу в отдельный поток, хоть не выноси. Если же для ее выполнения достаточно 80%-ной загрузки - значит, она будет 80%. А как же еще CPU может выполнить эту работу?
Anatoly Podgoretsky (2001-12-22 19:21:00) [2]Только для системы жесткогореального времени
panov (2001-12-22 11:31:00) [3]>Юрий Зотов © (21.12.01 21:58)
Я неправильно выразился, нужно было: "А разве в то время пока выполняется sleep, процессор не простаивает, если нет других задач".
"простаивает" в смысле "не занят полезной работой":-)
А во время Application.ProcessMessages процессор как я понимаю занят на полную катушку...
>Anatoly Podgoretsky © (21.12.01 22:39)
Я это и имел ввиду. Зачем, если для системы на данный момент нет полезной работы, загружать процессор?
Мне кажется, что непрерывный цикл оправдан только для системы реального режима времени?
А вызов sleep(n) как раз и позволяет загружать по-минимуму процессор в цикле.
Anatoly Podgoretsky (2001-12-21 22:39:00) [4]В WinXX это вроде бы именно так, но в других ОС может быть и иначе, например в Линухе процессор может переводиться в состояние HALT если для него нет работы, поэтому он там менее греется.
Юрий Зотов (2001-12-21 21:58:00) [5]Нет, конечно, он отдается системой другому потоку (того же процесса, или другого - неважно). Это было бы слишком расточительно.
Даже если написать Sleep(0), то процессор будет тут же отдан другому потоку. Сразу, а не по окончании кванта.
panov (2001-12-21 21:43:00) [6]А разве в то время пока выполняется sleep, процессор не простаивает?
Юрий Зотов (2001-12-21 21:39:00) [7]> panov © (21.12.01 21:21)
Поймите, ведь процессор ВСЕГДА загружен на 100%. Что значит, например, "загружен на 50%"? Что он, по полкоманды выполняет, что ли? Нет, конечно. Простаивает половину времени? Тоже нет, простаивать он тоже не умеет. Холостые циклы крутит? Так это тоже 100%-я загрузка.
А значит это, что в течение НЕКОТОРОГО интервала времени процессор 50% времени обслуживал ядро самой системы, а другие 50 - некие прикладные (с точки зрения ядра) задачи. Заметьте - "в течение НЕКОТОРОГО интервала времени" - того интервала, с периодичностью которого измеряется загруженность процессора.
То же самое и здесь. Процессор будет загружен на 100%, но только В ТЕЧЕНИЕ ОДНОГО ВИТКА ЦИКЛА И НЕ БОЛЕЕ КВАНТА ВРЕМЕНИ, ОТВЕДЕННОГО ДАННОМУ ПОТОКУ. А потом дело дойдет до ProcessMessages, программа обработает очередь сообщений и все пойдет по новой - пока не кончится квант. А по его окончании CPU будет отдан другой программе.
И даже если вынести цикл в другой поток, то загрузка процесора все равно будет 100% - но тоже в пределах одного кванта. Разница лишь в том, что при этом сообщения будут обрабатываться программой как бы одновременно с циклом. Точнее, программа сможет обрабатывать сообщения не в конце витка цикла, а в другом кванте - то есть, чаще. Вот и все.
panov (2001-12-21 21:21:00) [8]>Юрий Зотов © (21.12.01 21:10)
А разве если убрать sleep, процессор не будет загружен на 100%?
Другие процессы, конечно получат свое процессорное время, но я хочу видеть реальную загрузку процессора, а не бесконечный цикл.
Как мне кажется, самое лучшее, вынести обработку в отдельный поток с высоким приоритетом, обязательно оставив sleep(n).
Юрий Зотов (2001-12-21 21:10:00) [9]Если sleep убрать, то задержка будет ровно такой, какая и нужна. А соседи свое процессорное время все равно получат (если не играть с приоритетами), потому что в Wi32 ВЫТЕСНЯЮЩАЯ мультизадачность.
В общем - либо уберите sleep (он только мешает делу), либо выносите цикл в метод TThread.Execute.
Snake2000 (2001-12-21 18:14:00) [10]Если sleep убрать, на разных компах задержка будет разной
handra (2001-12-21 17:59:00) [11]sleep, как раз нужен - для того, чтобы отдать процессорное время другим приложениям (не надо забывать о соседях!)
Snake2000 (2001-12-21 17:58:00) [12]Помоги это реалмзовать, пожалуйста. Сам никогда с потоками не работал, так что вряд ли разберусь
Виктор Щербаков (2001-12-21 17:39:00) [13]Выполняй цикл в отдельном потоке. Поставь этому потоку нужный приоритет
Смотри TThread в хэлпе. Или в SDK Thread Functions.
Кстати Sleep в твоем коде не нужен.
Digitman (2001-12-21 17:37:00) [14]Что значит - "до завершения цикла, с окном работать невозможно" ??