C++でCPU使用率やメモリ使用量を調べる

絶対必要、というわけではないが200回以上も目視で記録するのは面倒なので(特にメモリの変化)調べてみた。

まずはCPU使用率。大まかな流れは以下の通り

1.PdhEnumObjectItemsで使用可能なパフォーマンスカウンタとインスタンス(要は調べたいプロセス)の一覧を取得する。
2.GetCurrentProcessIdでプロセスIDを取得(外部アプリケーションなら別途プロセスIDを求める必要あり)
3.パフォーマンスオブジェクト="Process"、パフォーマンスカウンタ="ID Process"のPDH_COUNTER_PATH_ELEMENTを生成
4.1.のmszCounterListの中からプロセスIDと同じインスタンスを求める。
5.PdhMakeCounterPathで、指定したインスタンスのパフォーマンスカウンタまでのパスを生成する。
6.PdhOpenQueryでパフォーマンスデータに対する新しい問い合わせ要求を生成。
7.PdhAddCounterで、5.で取得したカウンタのパスを新たな問い合わせカウンタとして追加。
8.PdhCollectDataで値を取得。
9.PdhGetFormattedCounterValueで実際の単位に修正する。
参考サイトです。
PdhEnumObjectItems 関数
PdhMakeCounterPath 関数
PdhOpenQuery 関数
PdhEnumObjectItems
PdhAddCounter

(汚い)コード例

必要なもの:pdh.hとpdh.libの宣言

char CounterNames[1024];
char InstanceNames[1024];
DWORD CounterSize=1024;
DWORD InstanceNameSize=1024;
char* cp;

PdhEnumObjectItemsA(NULL,
NULL,
"Process",
CounterNames,
&CounterSize,
InstanceNames,
&InstanceNameSize,
PERF_DETAIL_WIZARD,0);

/* インスタンス一覧から同じプロセスID を持つものを取得 */
cp = InstanceNames;
while(*cp != '\0') {
HQUERY hQuery;
HCOUNTER hCounter;
/* 新規クエリーを作成 */
PdhOpenQuery(NULL, 0, &hQuery);
/* プロセスID を取得するクエリを追加*/
char path[1024];
sprintf(path,"\\Process(%s#0)\\ID Process",cp);
PdhAddCounter(hQuery, path, 0, &hCounter);
/* データ(ID)を集めて取得 */
PdhCollectQueryData(&hQuery);
PdhGetFormattedCounterValue(hCounter, PDH_FMT_DOUBLE, NULL, &FmtValue);
if(GetCurrentProcessId()==FmtValue.longValue)
break;
cp += lstrlen(cp)+1
}
PDH_COUNTER_PATH_ELEMENTS cpe;
cpe.szObjectName="Process";
cpe.szCounterName="% Processor Time";
cpe.szInstanceName = "cp";
cpe.szParentInstance=NULL;
cpe.dwInstanceIndex=0;
cpe.szMachineName=NULL;

char CounterPath[1024];
DWORD pathSize = 1024;
PdhMakeCounterPath(&cpe,CounterPath,&pathSize,0);
HQUERY hQuery;
HCOUNTER hCounter;
PDH_FMT_COUNTERVALUE FmtValue;

/* 新規クエリーを作成 */
PdhOpenQuery(NULL, 0, &hQuery);

/* CPU使用率のカウンタをクエリーに追加 */
PdhAddCounter(hQuery, CounterPath, 0, &hCounter);

/* 計測 */
printf("計測開始...\n");
PdhCollectQueryData(hQuery);
PdhCollectQueryData(hQuery);
printf("計測終了.\n");
/* 今の十秒間での、CPUの使用率を表示 */
PdhGetFormattedCounterValue(hCounter, PDH_FMT_DOUBLE, NULL, &FmtValue);
printf("CPU使用率: %f%%\n", FmtValue.doubleValue);

ただし、マルチコアの場合ひとつのコアに関する使用率が求まるため、全体の値とは異なるんです。

メモリに関してはまた今度。