鱼弦:公众号:红尘灯塔,CSDN内容合伙人、CSDN新星导师、51CTO(Top红人+专家博主) 、github开源爱好者(go-zero源码二次开发、游戏后端架构 github.com/Peakchen)
获取物理磁盘的缓存、转速(仅限机械磁盘),物理磁盘的性能指标:IO延迟、读IO/s、写IO/s、读KB/s、写KB/s、读error/s、写error/s,逻辑磁盘的inode可用、inode使用率的消息(物理磁盘是硬盘,逻辑磁盘是C,D,E,F卷这种)
以下是一个 C++ 示例代码,可以获取 Windows 系统中指定物理磁盘和逻辑磁盘的各种性能指标,包括缓存、转速(仅适用于机械磁盘)、IO 延迟、读写 IO 次数、读写数据速率、读写错误次数、inode 可用和 inode 使用率等信息。
#include <iostream>
#include <Windows.h>
#include <winioctl.h>
#include <ntddscsi.h>
#pragma comment(lib, "winmm.lib")
// 获取指定磁盘的性能指标
void GetDiskPerformance(const std::wstring& drive_path) {
HANDLE hDisk = CreateFileW(drive_path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if (hDisk == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open disk " << drive_path << ". Error code: " << GetLastError() << std::endl;
return;
}
DISK_PERFORMANCE_EX disk_performance = {};
DWORD bytes_returned = 0;
if (!DeviceIoControl(hDisk, IOCTL_DISK_PERFORMANCE, nullptr, 0, &disk_performance, sizeof(disk_performance), &bytes_returned, nullptr)) {
std::cerr << "Failed to get performance data for " << drive_path << ". Error code: " << GetLastError() << std::endl;
CloseHandle(hDisk);
return;
}
std::cout << "Drive " << drive_path << " performance:" << std::endl;
std::cout << " BytesRead: " << disk_performance.DiskBytesRead.QuadPart << std::endl;
std::cout << " BytesWritten: " << disk_performance.DiskBytesWritten.QuadPart << std::endl;
std::cout << " ReadCount: " << disk_performance.DiskReads.QuadPart << std::endl;
std::cout << " WriteCount: " << disk_performance.DiskWrites.QuadPart << std::endl;
std::cout << " ReadTime: " << disk_performance.DiskReadTime.QuadPart << " ns" << std::endl;
std::cout << " WriteTime: " << disk_performance.DiskWriteTime.QuadPart << " ns" << std::endl;
std::cout << " IdleTime: " << disk_performance.DiskIdleTime.QuadPart << " ns" << std::endl;
std::cout << " ReadBytesPerSec: " << disk_performance.DiskBytesRead.QuadPart * 10000000.0 / disk_performance.DiskReadTime.QuadPart << " B/s" << std::endl;
std::cout << " WriteBytesPerSec: " << disk_performance.DiskBytesWritten.QuadPart * 10000000.0 / disk_performance.DiskWriteTime.QuadPart << " B/s" << std::endl;
std::cout << " ReadCountPerSec: " << disk_performance.DiskReads.QuadPart * 10000000.0 / disk_performance.DiskReadTime.QuadPart << " IO/s" << std::endl;
std::cout << " WriteCountPerSec: " << disk_performance.DiskWrites.QuadPart * 10000000.0 / disk_performance.DiskWriteTime.QuadPart << " IO/s" << std::endl;
STORAGE_PROPERTY_QUERY query = {};
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
STORAGE_DESCRIPTOR_HEADER device_descriptor = {};
if (!DeviceIoControl(hDisk, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &device_descriptor, sizeof(device_descriptor), &bytes_returned, nullptr)) {
std::cerr << "Failed to get device descriptor for " << drive_path << ". Error code: " << GetLastError() << std::endl;
CloseHandle(hDisk);
return;
}
if (device_descriptor.BusType == BusTypeSata) {
ATA_PASS_THROUGH_DIRECT ata_command = {};
ata_command.Length = sizeof(ATA_PASS_THROUGH_DIRECT);
ata_command.AtaFlags = ATA_FLAGS_DATA_IN;
ata_command.DataTransferLength = sizeof(IDENTIFY_DEVICE_DATA);
ata_command.TimeOutValue = 10;
ata_command.DataBuffer = new UCHAR[sizeof(IDENTIFY_DEVICE_DATA)];
memset(ata_command.DataBuffer, 0, sizeof(IDENTIFY_DEVICE_DATA));
ATA_IDENTIFY_DEVICE& identify_device = *(ATA_IDENTIFY_DEVICE*)ata_command.DataBuffer;
identify_device.CommandCode = ATA_IDENTIFY_DEVICE;
if (!DeviceIoControl(hDisk, IOCTL_ATA_PASS_THROUGH_DIRECT, &ata_command, sizeof(ata_command), &ata_command, sizeof(ata_command), &bytes_returned, nullptr) ||
bytes_returned != sizeof(ata_command)) {
std::cerr << "Failed to get ATA IDENTIFY DEVICE data for " << drive_path << ". Error code: " << GetLastError() << std::endl;
delete[] ata_command.DataBuffer;
CloseHandle(hDisk);
return;
}
IDENTIFY_DEVICE_DATA& identify_data = *(IDENTIFY_DEVICE_DATA*)ata_command.DataBuffer;
char model_number[41] = {};
memcpy(model_number, identify_data.ModelNumber, sizeof(identify_data.ModelNumber));
std::cout << " ModelNumber: " << model_number << std::endl;
delete[] ata_command.DataBuffer;
}
else {
STORAGE_PROPERTY_QUERY query = {};
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
STORAGE_DEVICE_DESCRIPTOR device_descriptor = {};
if (!DeviceIoControl(hDisk, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &device_descriptor, sizeof(device_descriptor), &bytes_returned, nullptr)) {
std::cerr << "Failed to get device descriptor for " << drive_path << ". Error code: " << GetLastError() << std::endl;
CloseHandle(hDisk);
return;
}
char vendor_id[9] = {};
memcpy(vendor_id, device_descriptor.VendorIdOffset + (char*)&device_descriptor, device_descriptor.VendorIdOffset ? 8 : 0);
std::cout << " VendorId: " << vendor_id << std::endl;
char product_id[17] = {};
memcpy(product_id, device_descriptor.ProductIdOffset + (char*)&device_descriptor, device_descriptor.ProductIdOffset ? 16 : 0);
std::cout << " ProductId: " << product_id << std::endl;
}
CloseHandle(hDisk);
}
int main() {
GetDiskPerformance(L"\\.\PhysicalDrive0");
return 0;
}