如何在Windows中计算当前进程的磁盘I/O使用百分比,就像任务管理器一样?

问题描述 投票:0回答:1

我正在尝试计算 Windows 中当前进程的磁盘 I/O 使用百分比,类似于任务管理器在“磁盘”列下显示的内容。但是,我一直无法获得准确的匹配。

我使用 psutil.Process.io_counters() 检索当前进程的读/写字节计数,但它似乎与任务管理器显示的内容不一致。具体来说,当使用 yara 等库进行文件扫描时,io_counters 读/写值似乎无法正确解释所有 I/O 操作。这可能是由于 YARA 如何处理内存中的文件读取或 Windows 如何跟踪此类操作的 I/O。

我需要什么:

计算当前进程磁盘I/O使用百分比的方法或工具,其方式与Windows任务管理器相匹配。 最好是基于 Python 的方法,但我对任何可靠的解决方案或库持开放态度。 深入了解为什么 psutil 可能无法反映使用 YARA 等特定库的进程的准确 I/O 统计信息。

我尝试过的:

使用 psutil.Process.io_counters() 获取读/写字节,但报告的值与任务管理器的磁盘使用情况不匹配。 探索系统级计数器(例如 Windows 中的性能计数器),但我无法弄清楚如何将它们映射到任务管理器的百分比值。 有没有办法可靠地计算当前进程的磁盘 I/O 百分比?或者有人可以澄清任务管理器如何计算这个指标?

python io taskmanager yara
1个回答
0
投票

第一句话:正如您提到的防止系统冻结,您很可能想要监视 ram 和 cpu 使用情况(现在我不是说 ram 就是性能的人),仍然是对于在磁盘上运行如此之多的任务,你可能要考虑监控盘了。
在这种情况下,您可以采取的最佳瞬时因素是%活动时间,正如我所说的“活动时间是磁盘不空闲时间的%”,如果需要的话,后面是读/写速度。

现在为了获取空闲时间数据,我没有找到一种方法

psutil
可以准确地做到这一点,它只有读取时间、写入时间的获取能力,因此请使用 Windows 性能计数器
win32pdh
。 代码如下:

import time
import win32pdh

def get_disk_active_time():
    try:
        # Counter path for % Idle Time
        idle_counter_path = r"\PhysicalDisk(_Total)\% Idle Time"

        # Create a performance counter query
        query_handle = win32pdh.OpenQuery()
        idle_counter = win32pdh.AddCounter(query_handle, idle_counter_path)

        # Collect the initial data sample
        win32pdh.CollectQueryData(query_handle)
        time.sleep(0.5)  # Wait for the counter to update

        # Collect the second data sample for calculation
        win32pdh.CollectQueryData(query_handle)
        _, idle_value = win32pdh.GetFormattedCounterValue(idle_counter, win32pdh.PDH_FMT_DOUBLE)

        # Active Time (%) = 100 - Idle Time (%)
        active_time = 100 - idle_value

        # Clean up
        win32pdh.CloseQuery(query_handle)

        return active_time

    except Exception as e:
        print(f"Error: {e}")
        return None

if __name__ == "__main__":
    print("Monitoring Disk Active Time (%): Press Ctrl+C to stop.")
    try:
        while True:
            active_time = get_disk_active_time()
            if active_time is not None:
                print(f"Disk Active Time: {active_time:.2f}%")
            time.sleep(1)
    except KeyboardInterrupt:
        print("\nMonitoring stopped.")

此代码输出的空值(0%)与任务管理器的空值匹配,并且值几乎相同(不是小数精度,而是精确到+-2%)。我很惊讶它显示 100%,并且与任务管理器执行时相同(同时复制一个大文件夹进行测试,后来我删除了),并且 90% 非常完美。

运行此代码不会导致内存相对于不运行此代码的时间增加,所以我认为这应该符合您的目的。

© www.soinside.com 2019 - 2024. All rights reserved.