Linux下通过遍历/proc目录获取PID列表最直接,Windows下必须用CreateToolhelp32Snapshot配合Process32First/Next。

Linux 下用 /proc 目录遍历获取进程列表最直接
Linux 没有统一的系统调用返回“所有进程列表”,但 /proc 是内核暴露进程信息的虚拟文件系统,每个数字子目录(如 /proc/1234)对应一个进程 ID。只要读取 /proc 下所有纯数字目录名,就能拿到 PID 列表。
实操建议:
- 用
opendir("/proc")+readdir()遍历,跳过非数字目录(如self、sys、net) - 对每个疑似 PID 的字符串调用
std::stoi或strtol转换,捕获异常或检查是否溢出(ERANGE) - 注意权限:某些进程(如其他用户或 root 进程)的
/proc/PID/目录可能不可读,stat()或open()失败时跳过即可,不必报错 - 不需要解析
/proc/PID/status或/proc/PID/cmdline就能拿到 PID;要命令行或状态才需进一步读取
Windows 下必须用 CreateToolhelp32Snapshot + Process32First/Next
Windows 没有类似 /proc 的文件接口,标准方式是调用 Windows API 的工具帮助库(Toolhelp)。核心是三步:快照 → 读首项 → 循环读下一项。
常见错误现象:
立即学习“C++免费学习笔记(深入)”;
- 忘记在循环前调用
Process32First,直接Process32Next会失败 -
PROCESSENTRY32结构体未初始化dwSize字段(必须设为sizeof(PROCESSENTRY32)),否则Process32First返回FALSE - 快照句柄没用
CloseHandle关闭,导致句柄泄漏
示例关键片段:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE) return;
PROCESSENTRY32 pe{ sizeof(pe) };
if (Process32First(hSnap, &pe)) {
do {
std::cout << pe.th32ProcessID << " " << pe.szExeFile << "\n";
} while (Process32Next(hSnap, &pe));
}
CloseHandle(hSnap);
跨平台封装要注意 pid_t 和 DWORD 的类型差异
Linux 返回的是 pid_t(通常为 int),Windows 是 DWORD(unsigned long)。如果写通用结构体存 PID,别直接用 int —— 用 std::int32_t 或 std::uint32_t 更稳妥,尤其当你要把 PID 存进容器或序列化时。
另外:
- 进程名在 Linux 通常从
/proc/PID/comm(短名)或/proc/PID/cmdline(带参数,需 null 分隔解析)读;Windows 直接从PROCESSENTRY32.szExeFile拿到可执行文件名(不含路径) - 不要假设进程名长度:Linux
/proc/PID/comm最多 16 字节(含 \0),WindowsszExeFile是MAX_PATH(260)字节,但实际常远小于此 - 没有“获取所有进程”原子操作,结果始终是某一时刻的快照;遍历时新进程可能启动、旧进程可能退出,这是正常现象
别用 ps 或 tasklist 命令解析输出来替代原生接口
调用 system("ps aux > /tmp/ps.out") 再读文件,看似简单,实际问题很多:
- 依赖 shell 和外部命令存在,嵌入式或最小化系统可能没有
ps - 输出格式不稳定:
ps的列顺序、空格数量、Unicode 字符都可能随 locale 或版本变化,正则或sscanf极易崩 - 权限更难控制:子进程继承父进程权限,但无法像
/proc/PID/那样细粒度跳过无权访问项 - 性能差:fork + exec + pipe + parse,比直接遍历
/proc或调用 Toolhelp 慢一个数量级
只有调试或临时脚本才考虑这种方式;生产代码一律走原生路径。
真正麻烦的不是怎么拿列表,而是后续想查某个进程的内存占用、父 PID、打开文件——那些字段在不同系统里散落在不同接口里,得按需补。

















