Windows 捕获磁盘IO量与磁盘活动时间(util)

windows下的底层开发相对Linux比较不方便,这里对主题做一些讨论,和贴一些自己写的代码。
磁盘IO可以由NtQuerySystemInformation获得(2号操作符),这个方法比较轻松,之前的获取CPU使用率也是这样。
但是磁盘的活动时间无法由NtQuerySystemInformation函数查询,因为他并没有提供有关磁盘时间的信息,或者队列情况。(也可能是有,我没有在网上找到资料。)
此外有两种方法获得磁盘详细信息,一种是PDH方法,一种是更底层的DeviceIoControl方法。
第二种方法实现起来比较复杂,不做研究,这里展示PDH方法。

#include 
#include 
#include 
#include 
#include 

#pragma comment(lib, "pdh.lib")

CONST ULONG SAMPLE_INTERVAL_MS    = 1000;

PDH_STATUS Status;
HQUERY Query = NULL;
HCOUNTER Counter;
PDH_FMT_COUNTERVALUE DisplayValue;
DWORD CounterType;

void init()
{

	char CounterPathBuffer[] = "\\PhysicalDisk(*)\\% Idle Time";

	//
	// Create a query.
	//

	Status = PdhOpenQuery(NULL, NULL, &Query);
	if (Status != ERROR_SUCCESS) 
	{
		wprintf(L"\nPdhOpenQuery failed with status 0x%x.", Status);
		goto Cleanup;
	}


	//ZeroMemory(&CounterPathBuffer, sizeof(CounterPathBuffer));

	//
	// Add the selected counter to the query.
	//

	Status = PdhAddCounter(Query, CounterPathBuffer, 0, &Counter);
	if (Status != ERROR_SUCCESS) 
	{
		wprintf(L"\nPdhAddCounter failed with status 0x%x.", Status);
		goto Cleanup;
	}

	Status = PdhCollectQueryData(Query);
	if (Status != ERROR_SUCCESS) 
	{
		wprintf(L"\nPdhCollectQueryData failed with 0x%x.\n", Status);
		goto Cleanup;
	}

	//
	// Print counter values until a key is pressed.
	//
	return;
Cleanup:
	if (Query) 
	{
		PdhCloseQuery(Query);
	}

}

void wmain(void)
{
	init();

	while (!_kbhit()) 
	{
		Sleep(SAMPLE_INTERVAL_MS);

		Status = PdhCollectQueryData(Query);
		if (Status != ERROR_SUCCESS) 
		{
			wprintf(L"\nPdhCollectQueryData failed with status 0x%x.", Status);
		}


		Status = PdhGetFormattedCounterValue(Counter,
			PDH_FMT_DOUBLE,
			&CounterType,
			&DisplayValue);
		if (Status != ERROR_SUCCESS) 
		{
			wprintf(L"\nPdhGetFormattedCounterValue failed with status 0x%x.", Status);
			goto Cleanup;
		}

		double DBIOUseTime = DisplayValue.doubleValue;

		if (DBIOUseTime > 100) DBIOUseTime = 100;

		DBIOUseTime = 100 - DBIOUseTime;

		wprintf(L"%0.2f%%\n", DBIOUseTime);
	}

Cleanup:

	//
	// Close the query.
	//

	if (Query) 
	{
		PdhCloseQuery(Query);
	}
}

需要注意的是,PDH方法采集的磁盘活动时间信息,是即时演算的,如果程序本身的活动时间和负载较大,会出现自身干扰。
出现这种情况,可以考虑Sleep 一段时间后再试。

此条目发表在C++, Windows, 系统, 编程分类目录,贴了, , 标签。将固定链接加入收藏夹。

Windows 捕获磁盘IO量与磁盘活动时间(util)》有1条回应

  1. 匿名说:

    加油。

发表评论

邮箱地址不会被公开。 必填项已用*标注