c – 如何获取全局Windows I / O统计信息?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c – 如何获取全局Windows I / O统计信息?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3829字,纯文字阅读大概需要6分钟。
内容图文
![c – 如何获取全局Windows I / O统计信息?](/upload/InfoBanner/zyjiaocheng/954/81d561734edb4c889cd94f65bacd657e.jpg)
WinAPI函数GetProcessIoCounters提供给定进程的所有I / O操作的详细信息:读取/写入操作的数量以及自进程启动以来读取/写入的字节数.最有可能的任务管理器使用此函数来显示这些数字:
是否有一种相对简单的方法来获得相同或相似的统计数据,但是从整个系统开始以来?
请注意,它与枚举所有当前进程并总结GetProcessIoCounters的结果不同,因为有些进程启动,运行一段时间并完成.当我调用GetProcessIoCounters时,这样的进程不再存在,但我想知道系统的整体I / O.
我打算每小时收集一次这些统计数据并将其记录到数据库中以供将来分析并帮助调试.
我正在寻找一种适用于没有WMI的Windows XP的方法(我们使用明显缩减的Windows XP Embedded),但如果这种方法仅适用于更高版本的Windows,请分享.最终它会很有用.
更新
我尝试了Jerry Coffin建议的DeviceIoControl(IOCTL_DISK_PERFORMANCE)方法.
我必须运行diskperf.exe -Y才能使它工作.我甚至没有重启,但没有它,DeviceIoControl失败,GetLastError = 31(连接到系统的设备无法运行.)DeviceIoControl在重新启动后继续工作而无需再次运行diskperf.exe -Y,但是重新启动后第一次调用DeviceIoControl在所有字段(BytesRead,BytesWritten,ReadCount,WriteCount)中返回零.进一步的调用返回非零统计数据.显然,系统启动时会有一些实质性的磁盘活动,但它没有被计算在内.因此,看起来重启后第一次调用DeviceIoControl确实启用/启动计数器.
如果我运行diskperf.exe -N,则DeviceIoControl会立即停止工作而无需重新启动.当我运行diskperf.exe -Y时,DeviceIoControl再次正常工作.
现在问题是:diskperf.exe -Y做了什么,以及如何在我的程序中做同样的事情?
更新2
我在diskperf.exe -Y之后和diskperf.exe -N之后导出整个注册表并查找差异.我能找到的唯一区别是一键:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PartMgr
"EnableCounterForIoctl"=dword:00000001
diskperf.exe -Y添加此密钥,diskperf.exe -N将其删除.
我试图将此密钥直接添加/删除到注册表中.
如果该密钥不存在且DeviceIoControl不起作用(在我运行diskperf.exe -N之后)并且我添加了这样的密钥:
reg add "HKLM\SYSTEM\CurrentControlSet\Services\PartMgr" /v EnableCounterForIoctl /t REG_DWORD /d 1
,然后DeviceIoControl立即开始工作.
如果密钥存在且DeviceIoControl正常工作(在我运行diskperf.exe -Y之后),我将删除此密钥,如下所示:
reg delete "HKLM\SYSTEM\CurrentControlSet\Services\PartMgr" /v EnableCounterForIoctl
然后DeviceIoControl继续工作,返回的统计信息不断增长.直到重启.
除了更改注册表值之外,diskperf.exe还必须执行其他操作,例如强制刷新/刷新注册表.在我的情况下,我关心启用这些计数器,它似乎与简单添加注册表项一起使用.
解决方法:
您可以使用DeviceIoControl一次获取一个磁盘数据,如下所示:
#include <windows.h>
#include <iostream>
int main() {
HANDLE dev = CreateFile("\\\\.\\C:",
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
DISK_PERFORMANCE disk_info { };
DWORD bytes;
if (dev == INVALID_HANDLE_VALUE) {
std::cerr << "Error opening disk\n";
return 1;
}
if (!DeviceIoControl(dev,
IOCTL_DISK_PERFORMANCE,
NULL,
0,
&disk_info,
sizeof(disk_info),
&bytes,
NULL))
{
std::cerr << "Failure in DeviceIoControl\n";
return 1;
}
std::cout.imbue(std::locale(""));
std::cout << "Bytes read: " << disk_info.BytesRead.QuadPart << "\n";
std::cout << "Bytes written: " << disk_info.BytesWritten.QuadPart << "\n";
}
例如,在我的机器上,这显示:
Bytes read: 15,768,173,568
Bytes written: 22,370,663,424
实验上,我得到的结果看起来很合理.例如,在插入闪存驱动器并打开其中一些图片的预览后,我得到:
Bytes read: 3,956,736
Bytes written: 0
要获取系统中当前可见的所有驱动器的数据,请添加对GetLogicalDrives或GetLogicalDriveStrings的调用,并在循环中调用此类代码,但为每个调用填写相应的驱动器号.
自从系统启动以来,这仍然不能保证是所有数据.例如,如果弹出可移动磁盘,则会丢失有关从该驱动器读取/写入内容的信息.如果将其重新插入,则只会获得自上次插入以来读取/写入内容的数据.
我完全不确定你能做多少比这更好,至少没有做大量的额外工作来定期收集数据并跟踪磁盘弹出和插入的时间等等. .当磁盘弹出时,我怀疑Windows几乎抛弃了有关该驱动器的所有统计信息,因此如果稍后重新插入,Windows将不再有关于弹出之前对其执行的操作的统计信息.
同样,如果磁盘已被弹出,因此它当前不可见,这将无法打开它,因此它也无法检索有关该驱动器的任何统计信息.
内容总结
以上是互联网集市为您收集整理的c – 如何获取全局Windows I / O统计信息?全部内容,希望文章能够帮你解决c – 如何获取全局Windows I / O统计信息?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。