EnumProcesses()vs CreateToolhelp32Snapshot()

jay*_*lee 26 c c++ windows winapi

我想知道两个Win32 API函数EnumProcesses()CreateToolhelp32Snapshot()之间是否存在任何差异(主要是性能方面的差异),用于枚举所有活动进程和已加载模块.或者,如果一个比另一个更好使用和为什么.

Luk*_*uke 15

我认为它们在性能(和结果)方面几乎相同,因为它们都调用相同的底层NT API,尽管CreateToolhelp32Snapshot()可能会有轻微的开销,因为它创建了一个section对象并将所有信息复制到它而EnumProcesses ()/ EnumProcessModules()直接与用户提供的缓冲区一起使用.但是,在现实世界中,差异可能是微不足道的.

我稍微喜欢EnumProcesses(),因为它(IMO)是一个更简单的API,但是如果需要,CreateToolhelp32Snapshot()会返回更多信息.EnumProcesses()的唯一缺点是你应该在一个循环中调用它,因为你可能没有分配足够大的缓冲区; CreateToolhelp32Snapshot()负责管理缓冲区管理.在实践中,我只是在堆栈上分配一个足够大的缓冲区来容纳1024个进程ID或模块句柄; 到目前为止,我还没有遇到这样一个系统,即这些限制中的任何一个甚至远远接近达到.当然,不久前我们对MAX_PATH说了同样的话,现在我们遇到了问题......

  • “足够容纳1024个进程ID”-在终端服务/远程桌面计算机上可以轻松耗尽,该服务为30个用户提供服务,每个进程有40个进程。 (2认同)

Ale*_*lex 15

以下是几个函数的结果:

  • EnumProcesses:16毫秒,207个进程
  • CreateToolhelp32Snapshot:141毫秒(16毫秒),207个进程
  • WTSEnumerateProcesses:16毫秒,207个进程
  • WTSEnumerateProcessesEx(WTS_CURRENT_SESSION):16毫秒,98个进程
  • WTSEnumerateProcessesEx(WTS_ANY_SESSION):16毫秒,207个进程

计算机在启用UAC的情况下运行Windows 8,用户未升级(例如,无法访问系统进程).主进程是32位,机器是64位,因此大量的64位进程.有:系统会话0,当前控制台用户会话1,另一个快速切换用户会话2.总共207个进程(这些都是32位和64位,包括伪"系统"进程) - 207也由Process Explorer确认.在这207个流程中:23个流程用于会话2,98个流程 - 用于会话1,剩余 - 用于会话0.

结果是10个单函数调用的循环.它们在每次运行中100%可重复.

对于CreateToolhelp32Snapshot,主要结果是调用CreateToolhelp32Snapshot本身,第二个结果(括号中)是循环使用First/Next.

我认为人们会混淆"枚举所有进程"(获取PID)和"获取进程/ exe的名称".第一个("枚举")与x32/x64交叉位无关.但后一个("获取名称")确实存在问题 - 并非每个方法都适用于x32/x64.


小智 5

我不记得确切,但与CreateToolhelp32Snapshot()不同,EnumProcesses()具有两个或两个限制之一:1.如果从x64 OS上的32位进程调用,则不枚举64位进程。2.不枚举Vista和Win7上提升的进程。