Windows用GetProcessHandleCount获取当前进程句柄数,需传GetCurrentProcess()句柄,结果通过输出参数返回;上限可通过GetProcessInformation+PROCESS_HANDLE_INFORMATION查询HandleCountLow字段,不支持时默认16777216。

Windows下用 GetProcessHandleCount 获取当前进程句柄数
Windows 提供了直接的 API:GetProcessHandleCount,它返回调用进程当前打开的有效句柄总数。这个值是实时、准确的,且开销极低。
- 必须传入当前进程的句柄,用
GetCurrentProcess()获取,不能传NULL或其他非法值 - 函数返回
BOOL,但实际计数通过输出参数lpdwHandleCount返回,别误以为返回值就是句柄数 - 注意:该计数包含所有内核对象句柄(文件、事件、互斥体、线程、窗口等),不区分类型
DWORD handleCount = 0;
if (GetProcessHandleCount(GetCurrentProcess(), &handleCount)) {
// handleCount 即当前已用句柄数
}Windows下查最大句柄限制靠 GetProcessInformation + ProcessHandleCount
Windows 没有全局统一的“最大句柄数”硬限制,实际限制由系统版本、内存和进程对象管理器决定。但自 Windows 8.1 / Server 2012 R2 起,可通过 GetProcessInformation 查询当前进程的句柄计数上限(PROCESS_HANDLE_INFORMATION)。
- 需启用
SE_DEBUG_PRIVILEGE权限才能查询其他进程;查自己进程通常无需提权 - 结构体
PROCESS_HANDLE_INFORMATION的HandleCountHigh字段在多数情况下为 0,真正有意义的是HandleCountLow—— 它代表当前允许的最大句柄数(不是已用数) - 如果
GetProcessInformation返回失败(如 ERROR_INVALID_PARAMETER),说明系统不支持该信息类,此时可保守按默认上限 16,777,216(即 2^24)估算,但实际远达不到
Linux 下没有等价的“句柄数”概念,得看 /proc/self/limits 和 /proc/self/fd/
Linux 中“句柄”对应文件描述符(fd),没有 Windows 那种统一的句柄抽象。因此要分两步:查已用数量、查软/硬限制。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 已用数:统计
/proc/self/fd/目录下条目数,scandir或std::filesystem::directory_iterator均可,注意跳过.和.. - 限制值:读取
/proc/self/limits,找Max open files行,解析 soft/hard limit 列(单位:个 fd) - 注意:
getrlimit(RLIMIT_NOFILE, &rl)返回的是当前生效的软限制,硬限制需额外调用或从/proc解析;且子进程继承父进程限制,但fork后不会自动重载
// 示例:获取当前 fd 数(POSIX)
int count = 0;
DIR* dir = opendir("/proc/self/fd");
if (dir) {
struct dirent* ent;
while ((ent = readdir(dir)) != nullptr) {
if (ent->d_type == DT_LNK) count++;
}
closedir(dir);
}跨平台封装要注意抽象层级和 fallback 行为
没有标准 C++ 接口能统一获取这两项指标,强行写宏封装容易掩盖差异。比如:
立即学习“C++免费学习笔记(深入)”;
- Windows 的
GetProcessHandleCount是精确值;Linux 的/proc/self/fd/统计虽准,但存在竞态(fd 可能在 readdir 过程中被 close) - Windows 的上限是动态内核资源池分配结果,Linux 的
RLIMIT_NOFILE是明确 setrlimit 设置的值 - 若你依赖此数据做资源预警,务必加缓存(如每秒采样一次),避免高频调用
/proc或频繁 API 调用影响性能
真正容易被忽略的是:句柄泄漏往往表现为“打开太多文件”错误,但根源可能在未关闭的 std::thread、未释放的 GDI 对象、或 WSAStartup 后未调用 WSACleanup —— 数值本身只是表象,关键还是配对清理逻辑。

















