在Windows系统下,C++可以通过调用系统提供的性能数据查询API来获取当前系统所有打开的句柄总数,这是进程资源监控场景中常用的功能实现方式。

核心API介绍
实现该功能主要依赖PDH(Performance Data Helper)库提供的接口,PDH是Windows系统用于查询性能计数器的标准工具库,能够获取系统各类资源的使用数据。我们需要用到的核心API包括:
PdhOpenQuery:打开一个性能查询句柄,用于后续的性能数据查询操作PdhAddCounter:向查询中添加需要获取的性能计数器,这里需要添加句柄总数的计数器路径PdhCollectQueryData:收集指定查询中的所有计数器数据PdhGetFormattedCounterValue:获取格式化后的计数器数值,也就是我们需要的句柄总数PdhCloseQuery:关闭查询句柄,释放相关资源
实现步骤详解
1. 初始化PDH库并打开查询
首先需要初始化PDH库,然后打开一个查询句柄,后续的所有计数器操作都基于这个查询句柄进行。
2. 添加句柄总数计数器
Windows系统中,句柄总数的性能计数器路径为Process(_Total)Handle Count,其中_Total表示所有进程的总和,添加该计数器后就可以获取系统全局的句柄总数。
3. 收集并获取计数器数据
添加计数器后,需要先调用收集数据接口获取一次数据,然后再调用获取格式化数值的接口拿到最终的句柄总数,注意第一次收集数据时可能无法获取到有效值,需要重复收集一次。
4. 释放资源
使用完查询句柄后,需要调用关闭接口释放资源,避免内存泄漏。
完整代码示例
以下是完整的C++实现代码,代码中包含了必要的注释说明每一步的作用:
#include <windows.h>
#include <pdh.h>
#include <iostream>
// 链接PDH库,否则编译会报错找不到相关函数
#pragma comment(lib, "pdh.lib")
int main() {
HQUERY hQuery = NULL;
HCOUNTER hCounter = NULL;
PDH_STATUS status;
DWORD dwValue;
PDH_FMT_COUNTERVALUE counterValue;
// 1. 打开性能查询句柄
status = PdhOpenQuery(NULL, 0, &hQuery);
if (status != ERROR_SUCCESS) {
std::cerr << "打开查询失败,错误码:" << status << std::endl;
return -1;
}
// 2. 添加句柄总数计数器,路径为所有进程的句柄计数总和
status = PdhAddCounter(hQuery, TEXT("\Process(_Total)\Handle Count"), 0, &hCounter);
if (status != ERROR_SUCCESS) {
std::cerr << "添加计数器失败,错误码:" << status << std::endl;
PdhCloseQuery(hQuery);
return -1;
}
// 3. 第一次收集数据,通常第一次收集无法获取有效值
status = PdhCollectQueryData(hQuery);
if (status != ERROR_SUCCESS && status != PDH_MORE_DATA) {
std::cerr << "第一次收集数据失败,错误码:" << status << std::endl;
PdhCloseQuery(hQuery);
return -1;
}
// 4. 第二次收集数据,此时可以获取有效值
status = PdhCollectQueryData(hQuery);
if (status != ERROR_SUCCESS && status != PDH_MORE_DATA) {
std::cerr << "第二次收集数据失败,错误码:" << status << std::endl;
PdhCloseQuery(hQuery);
return -1;
}
// 5. 获取格式化后的计数器数值,指定为长整型格式
status = PdhGetFormattedCounterValue(hCounter, PDH_FMT_LONG, NULL, &counterValue);
if (status != ERROR_SUCCESS) {
std::cerr << "获取计数器数值失败,错误码:" << status << std::endl;
PdhCloseQuery(hQuery);
return -1;
}
// 输出获取到的句柄总数
std::cout << "系统当前所有打开的句柄总数为:" << counterValue.longValue << std::endl;
// 6. 关闭查询句柄,释放资源
PdhCloseQuery(hQuery);
return 0;
}
注意事项
- 编译时需要链接
pdh.lib库,否则会出现未定义的外部符号错误,代码中已经通过#pragma comment(lib, "pdh.lib")自动链接,如果使用其他编译器需要手动配置链接选项。 - 性能计数器的数据收集需要一定的时间,第一次调用
PdhCollectQueryData时通常无法获取到有效数据,因此需要调用两次该接口才能保证获取到正确的数值。 - 如果需要获取单个进程的句柄数,只需要将计数器路径中的
_Total替换为对应进程的进程名即可,比如Process(calc)Handle Count表示获取计算器进程的句柄数。
该方法是Windows系统下获取句柄总数的标准实现方式,数据来源于系统性能计数器,准确性和实时性都有保障,适合用于进程资源监控工具的开发。
C++句柄获取进程资源监控Windows_API句柄总数统计修改时间:2026-06-12 13:54:42