admin 管理员组

文章数量: 1184232

看到 yrt888 提出的问题,抽空研究了一下,发现其实并不像网上那些示例写的,计算其实很简单,只要使用 SystemProcessorPerformanceInformation 参数反复调用 NtQuerySystemInformation,然后根据返回的 IdleTime, KernelTime, UserTime 值,分别用后一次调用取得的值减去前一次调用取得的值,得到各增量值,之后一个除法就得到使用率了。这里唯一要注意的就是 KernelTime 成员的值包含了 IdleTime 和核心调用使用时间。另外发现当使用 SystemBasicInformation 调用 NtQuerySystemInformation 来试图获取 cpu 个数时会失败,返回 0xC0000004 错误码,好在还有 GetSystemInfo 这个 api 可以用来查出 cpu 的个数。所以下面的示例中核心的部分只有一个方法,就是 getCpuTimeInfo,其它只是用来显示使用率的 GUI 界面设计。这个示例对系统安装的每个 cpu 分别使用一个自定义容器来显示使用率图像/数据,不过我们通常只有一个 cpu,而且即使有双核,一般的软件也只能使用到其中的一个,不过印象中有些影片编辑软件可以使用多处理器,例如像“小日本”。

示例代码只在 Windows2003+vfp9 上测试,其他环境未测试。

单独做成一个类来使用的示例:
由于示例中要使用 inkey 函数来延时,所以类库中不能在使用 vfp 自己的计时器来定义更新 cpu 使用率数据,否则 inkey 函数将导致 vfp 的计时器暂停运行,所以这里用 api 函数 SetTimer 来生成一个外部的计时器,并将类库的 updateUsage 方法绑定到这个计时器上。但这也会带了一些问题,因为 inkey 函数肯定也会使用 SetTimer 来创建计时器,这样就可能发生冲突,由于只是想示例 NtQuerySystemInformation 函数的用法,所以类库中也没有仔细处理这些问题,如果你要用它且遇到了问题,可能要从下面几个方面来着手解决:
1. 绑定到 _vfp.hwnd 的 WM_TIMER 事件之前,先用 GetWindowLong 获取并保存好 vfp 原来的缺省窗口处理过程。
2. 被绑定的 updateUsage 处理过程中,应该先判断 p3 是否就是我们定义的 TIMER_ID 值,如果是才执行其中的更新代码,否则调用第一步中保存的 _vfp 缺省处理过程。
3. 定义不同的 TIMER_ID 试试,例如: 0x12345
4. 如果你的程序中使用这个类库的代码段内没有使用 inkey 函数,就恢复使用 vfp 的计时器事件来调用 updateUsage 方法。

本文标签: 使用 调用 所以类库