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

Вниз

Определение загрузки процессора перед запуском проги   Найти похожие ветки 

 
Sergy   (2002-02-06 10:27) [0]

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


 
VuDZ   (2002-02-06 15:16) [1]

перевести сам смогёшь?
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3

#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))

typedef struct
{
DWORD dwUnknown1;
ULONG uKeMaximumIncrement;
ULONG uPageSize;
ULONG uMmNumberOfPhysicalPages;
ULONG uMmLowestPhysicalPage;
ULONG uMmHighestPhysicalPage;
ULONG uAllocationGranularity;
PVOID pLowestUserAddress;
PVOID pMmHighestUserAddress;
ULONG uKeActiveProcessors;
BYTE bKeNumberProcessors;
BYTE bUnknown2;
WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION;

typedef struct
{
LARGE_INTEGER liIdleTime;
DWORD dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;

typedef struct
{
LARGE_INTEGER liKeBootTime;
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION;


// ntdll!NtQuerySystemInformation (NT specific!)
//
// The function copies the system information of the
// specified type into a buffer
//
// NTSYSAPI
// NTSTATUS
// NTAPI
// NtQuerySystemInformation(
// IN UINT SystemInformationClass, // information type
// OUT PVOID SystemInformation, // pointer to buffer
// IN ULONG SystemInformationLength, // buffer size in bytes
// OUT PULONG ReturnLength OPTIONAL // pointer to a 32-bit
// // variable that receives
// // the number of bytes
// // written to the buffer
// );
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);

PROCNTQSI NtQuerySystemInformation;


void main(void)
{
SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIME_INFORMATION SysTimeInfo;
SYSTEM_BASIC_INFORMATION SysBaseInfo;
double dbIdleTime;
double dbSystemTime;
LONG status;
LARGE_INTEGER liOldIdleTime = {0,0};
LARGE_INTEGER liOldSystemTime = {0,0};

NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
GetModuleHandle("ntdll"),
"NtQuerySystemInformation"
);

if (!NtQuerySystemInformation)
return;

// get number of processors in the system
status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
if (status != NO_ERROR)
return;

printf("\nCPU Usage (press any key to exit): ");
while(!_kbhit())
{
// get new system time
status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
if (status!=NO_ERROR)
return;

// get new CPU"s idle time
status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
if (status != NO_ERROR)
return;

// if it"s a first call - skip it
if (liOldIdleTime.QuadPart != 0)
{
// CurrentValue = NewValue - OldValue
dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);

// CurrentCpuIdle = IdleTime / SystemTime
dbIdleTime = dbIdleTime / dbSystemTime;

// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5;

printf("\b\b\b\b%3d%%",(UINT)dbIdleTime);
}

// store new CPU"s idle and system time
liOldIdleTime = SysPerfInfo.liIdleTime;
liOldSystemTime = SysTimeInfo.liKeSystemTime;

// wait one second
Sleep(1000);
}
printf("\n");
}

работает только под NT но абсолютно точно


 
Sergy   (2002-02-06 16:01) [2]

>VuDZ
А мне и надо под NT.
перевести вряд ли, т.к. не силен в С (С++)
буду благодарен, если кто-то поможет.


 
VuDZ   (2002-02-06 16:07) [3]

ты говори, что не понятно, а я попытаюсь перевести на делфи или русский


 
Tosov   (2002-02-06 16:18) [4]


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Gauges, ExtCtrls, StdCtrls;

type
TForm1 = class(TForm)
Gauge1: TGauge;
Timer1: TTimer;
Button1: TButton;
CheckBox1: TCheckBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type SYSTEM_BASIC_INFORMATION=record
dwUnknown1 :DWORD;
uKeMaximumIncrement :ULONG;
uPageSize :ULONG;
uMmNumberOfPhysicalPages :ULONG;
uMmLowestPhysicalPage :ULONG;
uMmHighestPhysicalPage :ULONG;
uAllocationGranularity :ULONG;
pLowestUserAddress :Pointer;
pMmHighestUserAddress :Pointer;
uKeActiveProcessors :ULONG;
bKeNumberProcessors :BYTE;
bUnknown2 :BYTE;
wUnknown3 :WORD;
end;

type
SYSTEM_PERFORMANCE_INFORMATION=record
liIdleTime : LARGE_INTEGER;
dwSpare : array[0..76] of DWORD;
end;

type
SYSTEM_TIME_INFORMATION=record
liKeBootTime :LARGE_INTEGER;
liKeSystemTime :LARGE_INTEGER;
liExpTimeZoneBias :LARGE_INTEGER;
uCurrentTimeZoneId :ULONG;
dwReserved :DWORD;
end;

const
SystemBasicInformation =0;
SystemPerformanceInformation =2;
SystemTimeInformation =3;
var
Form1: TForm1;

function NtQuerySystemInformation(l:UINT;buff:Pointer;buffl:UINT;u:UINT):CARDINAL;stdcall;external "ntdll.dll";


implementation

{$R *.dfm}
function Li2Double(const x:LARGE_INTEGER):Double;
begin
Result:=x.HighPart*4.294967296E9 + x.LowPart;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
SysBaseInfo : SYSTEM_BASIC_INFORMATION;
SysTimeInfo : SYSTEM_TIME_INFORMATION;
SysPerfInfo : SYSTEM_PERFORMANCE_INFORMATION;
liOldIdleTime :LARGE_INTEGER;
liOldSystemTime :LARGE_INTEGER;
dbIdleTime :double;
dbSystemTime :double;
begin
liOldIdleTime.QuadPart:=0;
liOldSystemTime.QuadPart:=0;
if NtQuerySystemInformation(SystemBasicInformation,@SysBaseInfo,sizeof(SysBaseInfo),0)<>NO_ERROR
then exit;
repeat
if NtQuerySystemInformation(SystemTimeInformation,@SysTimeInfo,sizeof(SysTimeInfo),0)<>NO_ERROR
then exit;
if NtQuerySystemInformation(SystemPerformanceInformation,@SysPerfInfo,sizeof(SysPerfInfo),0)<>NO_ERROR
then exit;
if liOldIdleTime.QuadPart <> 0
then begin
// CurrentValue = NewValue - OldValue
dbIdleTime := Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime := Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);

// CurrentCpuIdle = IdleTime / SystemTime

dbIdleTime := dbIdleTime / dbSystemTime;

// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime := 100.0 - dbIdleTime * 100.0 / SysBaseInfo.bKeNumberProcessors + 0.5;

Gauge1.Progress:=Round(dbIdleTime);
end;
// store new CPU"s idle and system time
liOldIdleTime := SysPerfInfo.liIdleTime;
liOldSystemTime := SysTimeInfo.liKeSystemTime;


// wait one second
Sleep(1000);

Application.ProcessMessages;
if CheckBox1.Checked then exit;
until false;
end;

end.

Я не помню насколько близко к оригиналу я перевел, но по моему работало нормально (давно это было :)
На форме Gauge CheckBox и Button. В Gauge показывается загрузка проца (почти как в NT"шном таск менеджере). Прога вудет подвисать, т.к. не использовались потоки. При установке флажка в checkbox"е данные перестают обновляться и прога закроется.


 
VuDZ   (2002-02-06 16:22) [5]

да....
вот почему я люлю консоль - меньше писать левого кода надо...


 
Sergy   (2002-02-06 16:23) [6]

Я с API только начинаю разбираться, поэтому проблем у меня много.
Непонятно начинается сразу:
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3

#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))

Что есть SystemBasicInformation и т.д. Как я понимаю - это библиотеки, которые надобно подключить?


 
Sergy   (2002-02-06 16:25) [7]

Спасибо всем, попробую разобраться.


 
VuDZ   (2002-02-06 16:39) [8]

На делфийском:
const
integer SystemBasicInformation 0 и так далее

Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))
переводиться примерно так:
беруться первые 32 бита * 4.294967296E9 + нижние 32 бита
всё это преобразуется промежуточно в формат с плавающей точкой, что бы была выше точность

ЗЫ как в делфи выделить первые (последнии) биты - непомню... я бы сделал на асме, но может кто из гуру дефлей подскажет.


 
Tosov   (2002-02-06 17:07) [9]

VuDZ
На делфийском:
const
SystemBasicInformation=0;

>вот почему я люлю консоль - меньше писать левого кода надо...
Зато не так красиво :)
ЗЫ. В консоли было бы проще, но мне надо было именно график.



 
Sergy   (2002-02-06 18:05) [10]

> всем
Использовал код Tosov
Вопрос возник в процессе:
При перенесе кода в тело dll (ISAPI dll) вызвыаю ее припомощи запроса к веб серверу. При проверке оказывается, что
Round(dbIdleTime) возвращает -9223372036854775808.
В обычном приложении код работает идеально и возвращает то что нужно.
Вот код, правда я его немного изменил:

liOldIdleTime.QuadPart:=0;
liOldSystemTime.QuadPart:=0;
if NtQuerySystemInformation(SystemBasicInformation,@SysBaseInfo,sizeof(SysBaseInfo),0)<>NO_ERROR
then exit;
i:=0;
repeat
if NtQuerySystemInformation(SystemTimeInformation,@SysTimeInfo,sizeof(SysTimeInfo),0)<>NO_ERROR
then exit;
if NtQuerySystemInformation(SystemPerformanceInformation,@SysPerfInfo,sizeof(SysPerfInfo),0)<>NO_ERROR
then exit;
if liOldIdleTime.QuadPart <> 0
then begin
// CurrentValue = NewValue - OldValue
dbIdleTime := Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
dbSystemTime := Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);

// CurrentCpuIdle = IdleTime / SystemTime

dbIdleTime := dbIdleTime / dbSystemTime;

// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
dbIdleTime := 100.0 - dbIdleTime * 100.0 / SysBaseInfo.bKeNumberProcessors + 0.5;

response.Content:=Response.Content + "<br>"+ inttostr(Round(dbIdleTime));
inc(i);
end;
// store new CPU"s idle and system time
liOldIdleTime := SysPerfInfo.liIdleTime;
liOldSystemTime := SysTimeInfo.liKeSystemTime;
if i=1000 then
begin
Response.Content :=Response.Content+"<br>!!!" ;
Handled:=true;
exit;


end;
until false;



 
Dimaond Cat   (2002-02-07 00:24) [11]

2 VuDZ
выделить первые и последние биты можно с помощью shr и shl, это тебе на всякий случай, и если не ошибаюсь в сях есть такиеже функции



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

Форум: "WinAPI";
Текущий архив: 2002.04.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.007 c
1-22657
Serd_hhc
2002-03-26 14:09
2002.04.08
Как сменить текст моей консольной проги.


1-22641
DimaIv
2002-03-27 06:48
2002.04.08
Работа с масивом


1-22685
Kirill_Other
2002-03-26 09:51
2002.04.08
Как проверить имеет ли порожденный объект переопределенный метод?


1-22648
Сатир
2002-03-26 19:12
2002.04.08
Динамическое подключение пакетов


7-22868
EsKor
2002-01-11 05:48
2002.04.08
Работа с COM-портом





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