Windows下c++获取物理磁盘的性能指标

我想获取的是物理磁盘的性能指标:IO延迟、读IO/s、写IO/s、读KB/s、写KB/s、读error/s、写error/s(物理磁盘是disk0、disk1这种,不是c盘d盘这玩意)

你列的这些,有些是获取不了的,哪些能获取可以参考电脑自带的“性能监视器”
代码获取示例:

#include <windows.h>
#include <stdio.h>
#include <pdh.h>
#include <locale.h>
#include <wchar.h>
#include <stdlib.h>

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

typedef struct query_context{
    int count;
    PDH_HQUERY query;    
    PDH_HCOUNTER counter[20];
}query_context;

static query_context context_[16];
static WCHAR instance_names[4096]; 

//性能计数器名称,需要采集哪几个就在这里添加, 全部名称可通过list_counter_name()获取, 或通过系统自带“性能监视器”获取
static LPCWSTR counter_names_[] = {
    L"Disk Reads/sec",
    L"Disk Writes/sec",    
    L"Disk Read Bytes/sec",
    L"Disk Write Bytes/sec",        
    L"% Disk Time",    
};

//性能计数器对应显示名称
static LPCWSTR names_[] = {
    L"读次数/秒",
    L"写次数/秒",    
    L"读字节数/秒",
    L"写字节数/秒",        
    L"磁盘活动时间",    
};

#define check(exp,msg) if(!(exp)){printf("Error:%s\n",msg);exit(1);}

static void list_counter_name(){    
    WCHAR counter_names[4096];
    DWORD instance_length = 4096;
    DWORD counter_length = 4096;
    LPCWSTR counter_name;    
    PdhEnumObjectItemsW(NULL,NULL,L"PhysicalDisk",counter_names,&counter_length,instance_names,&instance_length,PERF_DETAIL_WIZARD,0);
    for(counter_name = counter_names; *counter_name; counter_name += (wcslen(counter_name) + 1)){
        wprintf(L"%ls\n", counter_name);
    }
}

static PDH_HCOUNTER add_counter(PDH_HQUERY query, LPCWSTR instance, LPCWSTR name){
    WCHAR path[1024];    
    PDH_HCOUNTER counter;
    PDH_STATUS stat;    
    _snwprintf(path, 1024, L"\\PhysicalDisk(%ls)\\%ls", instance, name);    
    stat = PdhAddCounterW(query, path, (DWORD_PTR)NULL, &counter);
     if(stat)return NULL;
    return counter;
}

static void get_disk_performance(LPCWSTR instance, int index){
    PDH_HQUERY query;
    PDH_HCOUNTER* counter;
    PDH_FMT_COUNTERVALUE value;    
    PDH_STATUS stat;    
    int i, count = 0;
    counter = context_[index].counter;
    query = context_[index].query;
    count = context_[index].count;
    if(!query){
        stat = PdhOpenQuery(NULL, (DWORD_PTR)NULL, &query); check(stat == 0, "PdhOpenQuery");
        context_[index].query = query;    
        for    (i=0; i<sizeof(counter_names_)/sizeof(LPCWSTR); i++){
            counter[count ++] = add_counter(query, instance, counter_names_[i]);     
        }
        context_[index].count = count;
    }
    wprintf(L"磁盘%d: (%ls)\n", index, instance);
    PdhCollectQueryData(query);
    for (i = 0; i < count; i++){        
        stat = PdhGetFormattedCounterValue(counter[i], PDH_FMT_DOUBLE, NULL, &value);        
        if(stat){
            wprintf(L"%ls 首次未采集\n", names_[i]);
        }else{
            wprintf(L"%ls %f\n", names_[i], value.doubleValue);
        }        
    }
    printf("\n");    
}

static void get_status(){    
    LPCWSTR instance ;
    int i = 0;
    for(instance = instance_names; *instance; instance += (wcslen(instance) + 1)){
        if(wcscmp(instance, L"_Total") == 0)continue;
        get_disk_performance(instance, i);
        i ++;
    }
}

int wmain(){
    setlocale(LC_ALL,"");    
    list_counter_name();    
    while(1){
        get_status();
        Sleep(1000);
        system("cls");
    }
    return 0;
}

你看下这个行不行。至于你说的物理磁盘,估计有点困难。windows下面基本上都是按照你划分的磁盘来计算的,应该有办法达到你想要的按照未划分的磁盘计算。


/* 头文件 */
#include <windows.h>
#include <stdio.h>
/* ************************************
 * BOOL GetDiskSpaceInfo(LPCSTR pszDrive
 * 功能 根据输入的驱动器,获取磁盘总容量
 *      空闲空间、簇数量等磁盘信息
 * 参数 驱动器根路径,比如“D:\”。
 **************************************/
BOOL GetDiskSpaceInfo(LPCSTR pszDrive)
{
  DWORD64 qwFreeBytesToCaller, qwTotalBytes, qwFreeBytes;
  DWORD dwSectPerClust, dwBytesPerSect, dwFreeClusters,  dwTotalClusters;
  BOOL bResult;
  //使用GetDiskFreeSpaceEx获取磁盘信息并打印结果
  bResult = GetDiskFreeSpaceEx (pszDrive,
    (PULARGE_INTEGER)&qwFreeBytesToCaller,
    (PULARGE_INTEGER)&qwTotalBytes,
    (PULARGE_INTEGER)&qwFreeBytes);
  if(bResult) 
  {
    printf("使用GetDiskFreeSpaceEx获取磁盘空间信息\n");
    printf("可获得的空闲空间(字节): \t%I64d\n", qwFreeBytesToCaller);
    printf("空闲空间(字节): \t\t%I64d\n", qwFreeBytes);
    printf("磁盘总容量(字节): \t\t%I64d\n", qwTotalBytes);
  }
  //使用GetDiskFreeSpace获取磁盘信息并打印结果
  bResult = GetDiskFreeSpace (pszDrive, 
    &dwSectPerClust, 
    &dwBytesPerSect,
    &dwFreeClusters, 
    &dwTotalClusters);
  if(bResult) 
  {
    printf("\n使用GetDiskFreeSpace获取磁盘空间信息\n");
    printf("空闲的簇数量 : \t\t\t%d\n",dwFreeClusters);
    printf("总簇数量 : \t\t\t%d\n",dwTotalClusters);
    printf("每簇的扇区数量 : \t\t%d\n",dwSectPerClust);
    printf("每扇区的容量(字节): \t\t%d\n",dwBytesPerSect);
    printf("空闲空间(字节): \t\t%I64d\n", 
      (DWORD64)dwFreeClusters*
      (DWORD64)dwSectPerClust*(DWORD64)dwBytesPerSect);
    printf("磁盘总容量(字节): \t\t%I64d",
      (DWORD64)dwTotalClusters*
      (DWORD64)dwSectPerClust*(DWORD64)dwBytesPerSect);
  }
  return bResult;
}
/* ************************************
 * int main( int argc, PCHAR argv[] )
 * 功能 应用程序主函数,根据输入参数
 *      调用GetDiskSpaceInfo函数获取
 *      磁盘空间信息
 * 参数 驱动器根路径,比如“D:\”。
 **************************************/
int main(int argc, PCHAR argv[])
{
  GetDiskSpaceInfo (argv[1]);
}


```

有一些软件和工具可以用来读取电脑磁盘的IO性能指标:
1、Nmon:这是一个用于监控系统性能的工具,可以显示磁盘的IOPS,带宽,响应时间等指标。
2、Iometer:这是一个用于测试磁盘IO能力的工具,可以模拟不同的IO负载和模式,测量磁盘的IOPS,带宽,延迟等指标。
3、IoZone:这是一个用于测试文件系统性能的工具,可以测量文件的读写速度,IOPS,延迟等指标。
具体软件你可以在网上下载,网上有这些工具的使用方法,很简单的。

使用PDH