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

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

Программа загружает процессор [D6, Win2k]


oleg krechetov ©   (2004-09-30 06:41:00) 

Доброго времени суток.

Есть программка опроса Сом - порта, на порту висит семь приборов, которые опрашиваются в цикле, цикл бесконечный, т.е. заканчивается принудительно. Программа при работе загружает процессор до 99%. Что можно сделать, как решить эту проблему. Хочу услышить Ваши мнения по решению этого вопроса.


DiamondShark   (2004-09-30 13:59:00) [1]


> и где собственно ожидание со чтением?

Вмдимо, тут:
U:=ExChange(SS,Pribor,TimeOut);

Весь остальной код, мало, что ужасный, так ещё и никакого отношения к порту не имеет.


simpson   (2004-09-30 12:36:00) [2]

> oleg krechetov   (30.09.04 12:29) [11]

О, ужас... :(
Какой тут COM-порт, если человек регулярно пишет конструкции типа

begin
 ComClose;
end;


Кроме того, где текст ComOpen и где собственно ожидание со чтением?
Это просто песня:

while ((TU+4*1.1574e-5)>Now) and (DwrdStop=0) do Application.ProcessMessages; // Задержка 4 сек.


Работу с портом в дополнительный поток, однозначно.


oleg krechetov   (2004-09-30 12:30:00) [3]

until DwrdStop<>0;
end;


Пришлось сократить все не входит :( . Отдельный поток поможет, в работе с пользовательскими процедурами - ButtonClick и д.р. Но он вряд ли уменьшит загрузку процессора. :(


oleg krechetov   (2004-09-30 12:29:00) [4]


procedure TForm1.ReadPribor(Pribor:integer);
const
Hour = 3600000/MSecsPerDay;
var
SS:ShortString;
II, K:integer;
TU:double;
CHAN:DWORD;
U:boolean;//
T:TDateTime;
AppPath:string;
begin
AppPath:= ExtractFilePath(Application.ExeName);
Query.DatabaseName:=AppPath+'DataBase\';
DwrdStop:=0;
CHAN:=0;{}
if not ComOpen(NumCom) then
begin
MessageDlg(ErrToStr(ComError),mtError,[mbCancel],0);
exit;
end;
if DwrdStop0 then
begin
ComClose;
end;
repeat
SS:='6;'+IntToStr(CHAN*8)+';8;';;
U:=ExChange(SS,Pribor,TimeOut);
if DwrdStop0 then
begin
ComClose;
CloseDataBase;
end;
if CHAN=0 then
begin
if Pribor = 1 then
begin
StatusBar2.Panels.Items[0].Text:='Ñòàòóñ: Îïðàøèâàåòñÿ ïðèáîð ¹ '+IntToStr(Pribor);
NumPribor:=Pribor;
ExitPribor:=Pribor;
Edit1.Text:=ANS[0];
Edit2.Text:=ANS[1];
if (StrToInt(ANS[2])1200) or((ANS[2])='$0')or((ANS[2])='$1') or((ANS[2])='$3') or((ANS[2])='$6') or((ANS[2])='$8')or((ANS[2])='$9') then
Edit3.Color:=clRed
else
Edit3.Color:=clBtnFace;
Edit3.Text:=ANS[2];
if(StrToInt(ANS[3])1100)or((ANS[3])='$0')                  or((ANS[3])='$1') or((ANS[3])='$3') or((ANS[3])='$6') or((ANS[3])='$8')                    or((ANS[3])='$9') then
                  Edit4.Color:=clRed
               else
                  Edit4.Color:=clBtnFace;
             Edit4.Text:=ANS[3];
               if (StrToInt(ANS[4])1100) or((ANS[4])='$0')
                   or((ANS[4])='$1') or((ANS[4])='$3') or((ANS[4])='$6') or((ANS[4])='$8')
                   or((ANS[4])='$9') then
                  Edit5.Color:=clRed
               else
                  Edit5.Color:=clBtnFace;
             Edit5.Text:=ANS[4];
               if (StrToInt(ANS[5])50) or((ANS[5])='$0')
                   or((ANS[5])='$1') or((ANS[5])='$3') or((ANS[5])='$6') or((ANS[5])='$8')
                   or((ANS[5])='$9') then
                  Edit6.Color:=clRed
               else
                  Edit6.Color:=clBtnFace;
             Edit6.Text:=ANS[5];
               if ((ANS[6])='$0')
                   or((ANS[6])='$1') or((ANS[6])='$3') or((ANS[6])='$6') or((ANS[6])='$8')
                   or((ANS[6])='$9') then
                  Edit55.Color:=clRed
               else
                  Edit55.Color:=clBtnFace;
             Edit55.Text:=ANS[6];
               if ((ANS[7])='$0')
                   or((ANS[7])='$1') or((ANS[7])='$3') or((ANS[7])='$6') or((ANS[7])='$8')
                   or((ANS[7])='$9') then
                  Edit56.Color:=clRed
               else
                  Edit56.Color:=clBtnFace;
             Edit56.Text:=ANS[7];
             OpenDataBase;
             SaveDataBase;
             CloseDataBase;
            end;
            end;

//--------------------------------------------------------------
inc(CHAN);
if CHAN>0 then
 begin
 CHAN:=0;
 inc(Pribor);
 if Pribor = 8 then
   begin
    Pribor:=1;
   end;
 TU:=Now;
 while ((TU+4*1.1574e-5)>Now) and (DwrdStop=0) do Application.ProcessMessages; // Задержка 4 сек.
 end;


Erik1   (2004-09-30 12:18:00) [5]

А применить копронент для работы с com портом гордость непозdоляет? Еще раз говорю если незнаеш как работать с устройствами используй готовые наработки. Они умеют работать с com портом в асинхроном режимеи вобще незагружают процесор. Еще можно по этому форому предварительно поиск сделать!


simpson   (2004-09-30 11:15:00) [6]

> oleg krechetov   (30.09.04 06:41)
> опрашиваются в цикле, цикл бесконечный, т.е.
> заканчивается принудительно

А нельзя ли увидеть код, который, собственно, производит опрос?


KSergey   (2004-09-30 11:11:00) [7]

Ну грузит. А в чем проблема-то?


Fedia   (2004-09-30 10:04:00) [8]

КаПиБаРа ©   (30.09.04 09:30) [6]
Я думаю что это будет работать. А вот загружать процессор на 99% совсем неправильно. Тем более что вопрос возник именно из-за этого.
Кроме того, никто и не утверждает, что вариант со sleep никуда не годится


КаПиБаРа   (2004-09-30 09:30:00) [9]

Fedia   (30.09.04 8:32) [4]
P.S.  sleep(0) едва ли поможет


Sleep(1) поможет.
Низкий приоритет при опросе внешних устройств подключенных на Com порт? Думаете это правильно?


MBo   (2004-09-30 08:52:00) [10]

>КаПиБаРа ©   (30.09.04 08:08) [3]
если в цикле опроса во втор. потоке вставлять sleep, то основной поток будет нормально работать, GUI будет откликаться. Конечно, более разумно, чтобы вторичный поток не тратил зря проц. время, а спал и ждал событий (wait-функции)


Fedia   (2004-09-30 08:32:00) [11]

>В дополнительном потоке бесконечный цикл не будет грузить процессор на 100%?
Если больше ни один из процессов не будет требовать процессорного времени, то может загрузить и на 100%. Но дополнительному потоку легко присвоить низкий приоритет, а в этом случае разрабатываемая программа будет охотно делиться процессорным временем с другими приложениями.
P.S.  sleep(0) едва ли поможет.


КаПиБаРа   (2004-09-30 08:08:00) [12]

MBo ©   (30.09.04 6:54) [1]
Опрос нужно проводить в дополнительном потоке (см. TThread)

В дополнительном потоке бесконечный цикл не будет грузить процессор на 100%?

oleg krechetov   (30.09.04 6:41)
Попробую погодать на кофейной гуще. Вставь sleep(0) в цикл опроса.


Fedia   (2004-09-30 07:15:00) [13]

Лучше чем [1] едва ли можно придумать, но у меня такой вариант:
после каждого шага цикла выполнять
Sleep(1000);
Application.ProcessMessages;
Интервал приостановки программы может варьироваться в зависимости от времени выполнения каждого шага цикла.


MBo   (2004-09-30 06:54:00) [14]

Опрос нужно проводить в дополнительном потоке (см. TThread)


Наверх

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