如何控制程序占用的CPU资源(只要谈谈想法或原理,不局限于Delphi)(200分)

  • 主题发起人 主题发起人 luyear
  • 开始时间 开始时间
真的能实现吗,我现在也要这方面的需要,如果是真的能不能给我发个信息:ctihy_cn@sina.com
 
2000 server中IIS好像也可以调整CPU占用率,比如不能超过10%,保证系统
其他任务的正常运行,professional版没有
 
就是就是,
不知道为什么,我的服务程序只要启动,CPU就100%,气死我了
请各位大哥点醒
 
编程时是不是也应该注意一下,尽量少占内存和 GDI 资源。
 
我的气死了,找了个VC的程序,转成D,N多问题,但CB却没事。

CB程序的正常,但一转成Delphi的就很多问题,那位有空改改,
如果成功了,多谢了告诉一声。各位老大帮俺试试

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Memo1: TMemo;
Timer1: TTimer;
Button1: TButton;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

const
MAX_RAW_VALUES = 20;

{$A-}
type
THandle = Pointer;
PHandle = ^THandle;

PPDH_RAW_COUNTER = ^TPDH_RAW_COUNTER;
_PDH_RAW_COUNTER = record
CStatus: DWORD;
TimeStamp: TFileTime;
FirstValue: Int64;
SecondValue: Int64;
MultiCount: DWORD;
end;
TPDH_RAW_COUNTER = _PDH_RAW_COUNTER;

PPDHCounterStruct = ^TPDHCounterStruct;
_tag_PDHCounterStruct = record
hCounter: THandle; // Handle to the counter - given to use by PDH Library
hNextIndex: Integer;
nOldestIndex: Integer;
nRawCount: Integer;
RawValue: array [0..MAX_RAW_VALUES - 1] of TPDH_RAW_COUNTER;
end;
TPDHCounterStruct = _tag_PDHCounterStruct;

PPDH_FMT_CouterValue = ^TPDH_FMT_CouterValue;
_PDH_FMT_COUNTERVALUE = record
CStatus: DWORD;
case Integer of
0: (longValue: DWORD);
1: (doubleValue: Double);
2: (largeValue: Int64);
3: (AnsiStringValue: PChar);
4: (WideStringValue: PWideChar);
end;
TPDH_FMT_CouterValue = _PDH_FMT_COUNTERVALUE;

const
Pdh = 'Pdh.dll';

function PdhOpenQuery(szDataSource: PChar; dwUserData: DWORD;
phQuery: PHandle): DWORD; stdcall; external Pdh name 'PdhOpenQueryA';

function PdhAddCounter(hQuery: THandle; const szFullCounterPath: PChar;
dwUserData: DWORD; phCounter: PHandle):
DWORD; stdcall; external Pdh name 'PdhAddCounterA';

function PdhCollectQueryData(hQuery: THandle): DWORD; stdcall; external Pdh name 'PdhCollectQueryData';
function PdhCloseQuery(hQuery: THandle): DWORD; stdcall; external Pdh name 'PdhCloseQuery';

function PdhGetFormattedCounterValue(hCounter: THandle; dwFormat: DWORD;
lpdwType: PDWORD; pValue: PPDH_FMT_CouterValue):
DWORD; stdcall; external Pdh name 'PdhGetFormattedCounterValue';

const
CounterPath: PChar = '/Processor(_Total)/% Processor Time';

type
TCpuUsage = class
private
FHandle: THandle;
FCounter: TPDHCounterStruct;
function InitUsage: Boolean;
public
constructor Create;
destructor Destroy; override;
function GetUsage: Integer;
end;

{ TCpuUsage }

constructor TCpuUsage.Create;
begin
inherited Create;
FHandle := nil;
FillChar(FCounter, Sizeof(FCounter), 0);
if not InitUsage then
raise Exception.Create(SysErrorMessage(GetLastError));
end;

destructor TCpuUsage.Destroy;
begin
if FHandle <> nil then
PdhCloseQuery(FHandle);
inherited Destroy;
end;

function TCpuUsage.GetUsage: Integer;
const
PDH_FMT_LONG = $100;
var
Formatted: TPDH_FMT_CouterValue;
begin
if ERROR_SUCCESS <> PdhCollectQueryData(FHandle) then
raise Exception.Create(SysErrorMessage(GetLastError));
if PdhGetFormattedCounterValue(FCounter.hCounter, PDH_FMT_LONG,
nil, @Formatted) = ERROR_SUCCESS then
Result := Formatted.longValue
else
Result := 0;
end;

function TCpuUsage.InitUsage: Boolean;
begin
Result := FHandle <> nil;
if Result then Exit;
Result := PdhOpenQuery(nil, 1, @FHandle) = ERROR_SUCCESS;
if not Result then Exit;
Result := PdhAddCounter(FHandle, CounterPath,
DWORD(@FCounter), @FCounter.hCounter) = ERROR_SUCCESS;
end;

var
Usage: TCpuUsage = nil;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Memo1.Lines.Add(Format('CPU Usage: %d', [Usage.GetUsage]))
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Usage := TCpuUsage.Create;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Usage.Free;
end;
{$A+}
end.



#include <vcl.h>
#pragma hdrstop

#include "pdh.h"
#include "Unit1.h"

#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

#define MAX_RAW_VALUES 20

const char szCounterName[] = "//Processor(_Total)//% Processor Time";

typedef struct _tag_PDHCounterStruct {
HCOUNTER hCounter; // Handle to the counter - given to use by PDH Library
int nNextIndex; // element to get the next raw value
int nOldestIndex; // element containing the oldes raw value
int nRawCount; // number of elements containing raw values
PDH_RAW_COUNTER a_RawValue[MAX_RAW_VALUES]; // Ring buffer to contain raw values
} PDHCOUNTERSTRUCT, *PPDHCOUNTERSTRUCT;

class CCpuUsage
{
private:
PDHCOUNTERSTRUCT m_CounterStruct;
HQUERY m_hQuery;
public:
CCpuUsage()
{
m_hQuery = NULL;
memset(&m_CounterStruct, 0, sizeof(m_CounterStruct));
};
virtual ~CCpuUsage()
{
PdhCloseQuery(m_hQuery);
};
BOOL Init()
{
if (ERROR_SUCCESS != PdhOpenQuery(NULL, 1, &m_hQuery))
return FALSE;
PDH_STATUS pdh_status = PdhAddCounter(m_hQuery, szCounterName,
(DWORD)&m_CounterStruct, &(m_CounterStruct.hCounter));
if (ERROR_SUCCESS != pdh_status)
{
return FALSE;
}
return TRUE;
};
int GetUsage()
{
PDH_FMT_COUNTERVALUE pdhFormattedValue;
PdhCollectQueryData(m_hQuery);
if (ERROR_SUCCESS != PdhGetFormattedCounterValue(
m_CounterStruct.hCounter, PDH_FMT_LONG, NULL, &pdhFormattedValue))
{
return 0;
}
return pdhFormattedValue.longValue;
};
};

CCpuUsage *Cpu;

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Cpu = new CCpuUsage;
Cpu->Init();
}

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
Label1->Caption = Cpu->GetUsage();
}

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
delete Cpu;
}
 
上面的程序是取CPU的使用频率的,但转成D老是有问题,但在CB中却是正常,请教了N人,
我的结果是:准备做成C的DLL。没办法了。
 
哦,我的思路是,检测到CPU的使用率,如在70%以下,则Sleep一下,再Loop,就这么简单。
[:D]
 

Similar threads

后退
顶部