Jay*_*Jay 8 c python winapi pid
我意识到"快"有点主观所以我会用一些背景来解释.我正在研究一个名为psutil的Python模块,用于以跨平台的方式读取流程信息.其中一个功能是pid_exists(pid)
用于确定PID是否在当前进程列表中的功能.
现在我这样做是显而易见的,使用EnumProcesses()来拉动进程列表,然后通过列表进行交互并查找PID.但是,一些简单的基准测试显示,这比基于UNIX的平台(Linux,OS X,FreeBSD)上的pid_exists函数要慢得多,我们使用kill(pid, 0)
0信号来确定PID是否存在.额外的测试表明它的EnumProcesses几乎一直在占据.
任何人都知道比使用EnumProcesses更快的方法来确定PID是否存在?我尝试了OpenProcess()并检查是否有错误打开不存在的进程,但结果比通过EnumProcesses列表迭代慢了4倍,所以也是如此.还有其他(更好的)建议吗?
注意:这是一个Python库,旨在避免第三方lib依赖项,如pywin32扩展.我需要一个比我们当前代码更快的解决方案,它不依赖于pywin32或标准Python发行版中没有的其他模块.
编辑:澄清 - 我们很清楚,阅读过程中存在固有的竞争条件.如果在数据收集过程中进程消失或者遇到其他问题,我们会引发异常.pid_exists()函数无意替换正确的错误处理.
更新:显然我早期的基准测试存在缺陷 - 我用C语言编写了一些简单的测试应用程序,EnumProcesses的编写速度一直较慢,OpenProcess(与PID有效但过程已经停止时一起使用GetProcessExitCode)实际上要快得多而且速度慢.
事实证明,我的基准测试显然存在某种缺陷,因为后来的测试表明 OpenProcess 和 GetExitCodeProcess 毕竟比使用 EnumProcesses 快得多。我不确定发生了什么,但我做了一些新的测试并验证这是更快的解决方案:
int pid_is_running(DWORD pid)
{
HANDLE hProcess;
DWORD exitCode;
//Special case for PID 0 System Idle Process
if (pid == 0) {
return 1;
}
//skip testing bogus PIDs
if (pid < 0) {
return 0;
}
hProcess = handle_from_pid(pid);
if (NULL == hProcess) {
//invalid parameter means PID isn't in the system
if (GetLastError() == ERROR_INVALID_PARAMETER) {
return 0;
}
//some other error with OpenProcess
return -1;
}
if (GetExitCodeProcess(hProcess, &exitCode)) {
CloseHandle(hProcess);
return (exitCode == STILL_ACTIVE);
}
//error in GetExitCodeProcess()
CloseHandle(hProcess);
return -1;
}
Run Code Online (Sandbox Code Playgroud)
请注意,您确实需要使用,GetExitCodeProcess()
因为OpenProcess()
它将在最近死亡的进程上成功,因此您不能假设有效的进程句柄意味着该进程正在运行。
另请注意,OpenProcess()
对于任何有效 PID 的 3 以内的 PID,该方法会成功(请参阅为什么即使我向进程 ID 添加 3,OpenProcess 也会成功?)
归档时间: |
|
查看次数: |
6483 次 |
最近记录: |