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

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

Здадержка [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]

Что значит - "до завершения цикла, с окном работать невозможно" ??


Наверх

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